This is an automated email from the ASF dual-hosted git repository.
andy pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/jena.git
The following commit(s) were added to refs/heads/main by this push:
new 9e942990ef GH-2902: Fix: Work with Shiro-style resource names
9e942990ef is described below
commit 9e942990ef0874f0ef44c7c84535d6d4150545aa
Author: Andy Seaborne <[email protected]>
AuthorDate: Wed Jan 1 15:47:03 2025 +0000
GH-2902: Fix: Work with Shiro-style resource names
---
.../java/org/apache/jena/atlas/lib/IRILib.java | 133 ++++++++++-----------
.../main/java/org/apache/jena/atlas/lib/Lib.java | 9 ++
.../apache/jena/fuseki/mod/shiro/FMod_Shiro.java | 21 ++--
.../jena/fuseki/mod/shiro/FusekiShiroLib.java | 41 +++++--
.../apache/jena/fuseki/mod/shiro/TestModShiro.java | 27 ++++-
.../testing/Shiro/shiro withSpaceInName.ini | 13 ++
.../org/apache/jena/tdb1/store/TestNodeId.java | 64 +++++-----
7 files changed, 187 insertions(+), 121 deletions(-)
diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/IRILib.java
b/jena-base/src/main/java/org/apache/jena/atlas/lib/IRILib.java
index 021d6d996f..2e0d92cd81 100644
--- a/jena-base/src/main/java/org/apache/jena/atlas/lib/IRILib.java
+++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/IRILib.java
@@ -18,12 +18,12 @@
package org.apache.jena.atlas.lib;
-import java.io.File ;
+import java.io.File;
import java.net.URLEncoder;
import java.nio.file.Path;
-import org.apache.jena.atlas.AtlasException ;
-import org.apache.jena.base.Sys ;
+import org.apache.jena.atlas.AtlasException;
+import org.apache.jena.base.Sys;
/** Operations related to IRIs.
* <p>
@@ -50,7 +50,7 @@ public class IRILib
* segment = *pchar
* segment-nz = 1*pchar
* segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
- * ; non-zero-length segment without any colon ":"
+ * ; non-zero-length segment without any colon ":"
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
* query = *( pchar / "/" / "?" )
* fragment = *( pchar / "/" / "?" )
@@ -66,10 +66,10 @@ public class IRILib
// Not allowed in URIs, and '%'
private static char uri_non_chars[] = {
'%', '"', '<', '>', '{', '}', '|', '\\', '`', '^', ' ', '\n', '\r',
'\t', '£'
- } ;
+ };
// RFC 2396
- //private static char uri_unwise[] = { '{' , '}', '|', '\\', '^', '[',
']', '`' } ;
+ //private static char uri_unwise[] = { '{' , '}', '|', '\\', '^', '[',
']', '`' };
// Javascript: A-Z a-z 0-9 - _ . ! ~ * ' ( )
// URLEncoder.encode(string)
@@ -85,9 +85,9 @@ public class IRILib
* Include ':' (segment-nc) and '/' (segment separator).
*/
private static char[] charsComponent = {
- //
+ // reserved : sub-delims and gen-delims
'!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=', ':', '/', '?',
'#', '[', ']', '@',
- // Other
+ // Other ASCII characters that should be encoded
'%', '"', '<', '>', '{', '}', '|', '\\', '`', '^', ' ', '\n', '\r',
'\t', '£'
};
@@ -99,7 +99,7 @@ public class IRILib
'!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=',/* ':', '/',*/
'?', '#', '[', ']', '@',
// Other
'%', '"', '<', '>', '{', '}', '|', '\\', '`', '^', ' ', '\n', '\r',
'\t', '£'
- } ;
+ };
// segment = *pchar
// pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
@@ -131,22 +131,20 @@ public class IRILib
};
// The initializers must have run.
- static final String cwd ;
- static final String cwdURL ;
+ private static final String cwdURL;
// Current directory, with trailing "/"
// This matters for resolution.
static {
- String x = new File(".").getAbsolutePath() ;
- x = x.substring(0, x.length()-1) ;
- cwd = x ;
- cwdURL = plainFilenameToURL(cwd) ;
+ String cwd = new File(".").getAbsolutePath();
+ cwd = cwd.substring(0, cwd.length()-1);
+ cwdURL = plainFilenameToURL(cwd);
}
// See also IRIResolver
/** Return a string that is an IRI for the filename.*/
public static String fileToIRI(File f) {
- return filenameToIRI(f.getAbsolutePath()) ;
+ return filenameToIRI(f.getAbsolutePath());
}
/** Create a string that is a IRI for the filename.
@@ -158,32 +156,32 @@ public class IRILib
* </ul>
*/
public static String filenameToIRI(String fn) {
- if ( fn == null ) return cwdURL ;
-
- if ( fn.length() == 0 ) return cwdURL ;
-
+ if ( fn == null )
+ return cwdURL;
+ if ( fn.length() == 0 )
+ return cwdURL;
if ( fn.startsWith("file:") )
- return normalizeFilenameURI(fn) ;
- return plainFilenameToURL(fn) ;
+ return normalizeFilenameURI(fn);
+ return plainFilenameToURL(fn);
}
/** Convert a file: IRI to a filename */
public static String IRIToFilename(String iri) {
if ( ! iri.startsWith("file:") )
- throw new AtlasException("Not a file: URI: "+iri) ;
+ throw new AtlasException("Not a file: URI: "+iri);
- String fn ;
+ String fn;
if ( iri.startsWith("file:///") )
- fn = iri.substring("file://".length()) ;
+ fn = iri.substring("file://".length());
else
- fn = iri.substring("file:".length()) ;
+ fn = iri.substring("file:".length());
// MS Windows: we can have
// file:///C:/path or file:/C:/path
// At this point, we have a filename of /C:/
// so need strip the leading "/"
fn = fixupWindows(fn);
- return decodeHex(fn) ;
+ return decodeHex(fn);
}
/** Convert a plain file name (no file:) to a file: URL */
@@ -191,43 +189,41 @@ public class IRILib
// No "file:"
// Make Absolute filename.
- boolean trailingSlash = fn.endsWith("/") ;
+ boolean trailingSlash = fn.endsWith("/");
// To get Path.toAbsolutePath to work, we need to convert /C:/ to C:/
// then back again.
- fn = fixupWindows(fn) ;
+ fn = fixupWindows(fn);
try {
// Windows issue
// Drive letter may not exists in which case it has no working
directory "x:"
- fn = Path.of(fn).toAbsolutePath().normalize().toString() ;
+ fn = Path.of(fn).toAbsolutePath().normalize().toString();
} catch (java.io.IOError ex) {
// Any IO problems - > ignore.
}
if ( trailingSlash && ! fn.endsWith("/") )
- fn = fn + "/" ;
+ fn = fn + "/";
- if ( Sys.isWindows )
- {
+ if ( Sys.isWindows ) {
// C:\ => file:///C:/...
if ( windowsDrive(fn, 0) )
// Windows drive letter - already absolute path.
// Make "URI" absolute path
- fn = "/"+fn ;
+ fn = "/"+fn;
// Convert \ to /
// Maybe should do this on all platforms? i.e consistency.
- fn = fn.replace('\\', '/' ) ;
+ fn = fn.replace('\\', '/' );
}
- fn = encodeFileURL(fn) ;
- return "file://"+fn ;
+ fn = encodeFileURL(fn);
+ return "file://"+fn;
}
// Case of Windows /C:/ which can come from URL.toString
// giving file:/C:/ and decoding file:///C:/
private static String fixupWindows(String fn) {
- if ( Sys.isWindows &&
- fn.length() >= 3 && fn.charAt(0) == '/' && windowsDrive(fn, 1))
- fn = fn.substring(1) ;
+ if ( Sys.isWindows && fn.length() >= 3 && fn.charAt(0) == '/' &&
windowsDrive(fn, 1))
+ fn = fn.substring(1);
return fn;
}
@@ -235,37 +231,36 @@ public class IRILib
* The test is can we find "C:" at location {@code i}.
*/
private static boolean windowsDrive(String fn, int i) {
- return
- fn.length() >= 2+i &&
- fn.charAt(1+i) == ':' &&
- isA2Z(fn.charAt(i)) ;
+ return fn.length() >= 2+i &&
+ fn.charAt(1+i) == ':' &&
+ isA2Z(fn.charAt(i));
}
private static boolean isA2Z(char ch) {
- return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') ;
+ return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z');
}
/** Sanitize a "file:" URL. Must start "file:" */
private static String normalizeFilenameURI(String fn) {
if ( ! fn.startsWith("file:/") ) {
// Relative path.
- String fn2 = fn.substring("file:".length()) ;
- return plainFilenameToURL(fn2) ;
+ String fn2 = fn.substring("file:".length());
+ return plainFilenameToURL(fn2);
}
// Starts file:// or file:///
if ( fn.startsWith("file:///") )
// Assume it's good and return as-is.
- return fn ;
+ return fn;
if ( fn.startsWith("file://") ) {
// file: URL with host name (maybe!)
- return fn ;
+ return fn;
}
// Must be file:/
- String fn2 = fn.substring("file:".length()) ;
- return plainFilenameToURL(fn2) ;
+ String fn2 = fn.substring("file:".length());
+ return plainFilenameToURL(fn2);
}
/** Encode using the rules for a component (e.g. ':' and '/' get encoded)
@@ -273,8 +268,8 @@ public class IRILib
* Does not encode non-ASCII characters
*/
public static String encodeUriComponent(String string) {
- String encStr = StrUtils.encodeHex(string,'%', charsComponent) ;
- return encStr ;
+ String encStr = StrUtils.encodeHex(string,'%', charsComponent);
+ return encStr;
}
/**
@@ -285,17 +280,17 @@ public class IRILib
* query part but it is then a legal, character.
*/
public static String encodeUriQueryFrag(String string) {
- String encStr = StrUtils.encodeHex(string,'%', charsQueryFrag) ;
+ String encStr = StrUtils.encodeHex(string,'%', charsQueryFrag);
// Space is special.
String encStr1 = encStr.replace("%20", "+");
- return encStr1 ;
+ return encStr1;
}
public static String decodeUriQueryFrag(String string) {
// Space is special. Reverse order compared to encodeUriQueryFrag
String decStr0 = string.replace("+", " ");
- String decStr = StrUtils.decodeHex(decStr0,'%') ;
- return decStr ;
+ String decStr = StrUtils.decodeHex(decStr0,'%');
+ return decStr;
}
@@ -303,8 +298,8 @@ public class IRILib
* Does not encode non-ASCII characters
*/
public static String encodeFileURL(String string) {
- String encStr = StrUtils.encodeHex(string,'%', charsFilename) ;
- return encStr ;
+ String encStr = StrUtils.encodeHex(string,'%', charsFilename);
+ return encStr;
}
/** Encode using the rules for a path (e.g. ':' and '/' do not get
encoded) */
@@ -312,16 +307,16 @@ public class IRILib
// Not perfect.
// Encode path.
// %-encode chars.
- uri = StrUtils.encodeHex(uri, '%', charsPath) ;
- return uri ;
+ uri = StrUtils.encodeHex(uri, '%', charsPath);
+ return uri;
}
public static String encodeNonASCII(String string) {
if ( ! containsNonASCII(string) )
- return string ;
+ return string;
- byte[] bytes = StrUtils.asUTF8bytes(string) ;
- StringBuilder sw = new StringBuilder() ;
+ byte[] bytes = StrUtils.asUTF8bytes(string);
+ StringBuilder sw = new StringBuilder();
for ( byte b : bytes ) {
// Signed bytes ...
if ( b > 0 ) {
@@ -335,16 +330,16 @@ public class IRILib
sw.append( Chars.hexDigitsUC[hi] );
sw.append( Chars.hexDigitsUC[lo] );
}
- return sw.toString() ;
+ return sw.toString();
}
public static boolean containsNonASCII(String string){
- for ( int i = 0 ; i < string.length() ; i++ ) {
- char ch = string.charAt(i) ;
+ for ( int i = 0; i < string.length(); i++ ) {
+ char ch = string.charAt(i);
if ( ch >= 127 )
return true;
}
- return false ;
+ return false;
}
/**
@@ -359,6 +354,6 @@ public class IRILib
* It will not decode '+' used for space
(application/x-www-form-urlencoded).
*/
public static String decodeHex(String string) {
- return StrUtils.decodeHex(string, '%') ;
+ return StrUtils.decodeHex(string, '%');
}
}
diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/Lib.java
b/jena-base/src/main/java/org/apache/jena/atlas/lib/Lib.java
index 72c8c496c9..ac8a079dfb 100644
--- a/jena-base/src/main/java/org/apache/jena/atlas/lib/Lib.java
+++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/Lib.java
@@ -172,6 +172,15 @@ public class Lib
return x;
}
+ /**
+ * Set the environment name in the java system properties (NB not the
immutable
+ * process environment variables). {@link #getenv(String)} looks in the
system
+ * properties as well as the process environment variables.
+ */
+ public static void setenv(String sysPropName, String value) {
+ System.getProperties().setProperty(sysPropName, value);
+ }
+
/** Test whether a property (environment variable or system property) is
true. */
public static boolean isPropertyOrEnvVarSetToTrue(String name) {
return isPropertyOrEnvVarSetToTrue(name, name);
diff --git
a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/shiro/FMod_Shiro.java
b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/shiro/FMod_Shiro.java
index 646505c8b9..419df8e337 100644
---
a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/shiro/FMod_Shiro.java
+++
b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/shiro/FMod_Shiro.java
@@ -24,7 +24,6 @@ import java.util.Set;
import jakarta.servlet.Filter;
import org.apache.jena.atlas.io.IOX;
-import org.apache.jena.atlas.lib.IRILib;
import org.apache.jena.atlas.lib.Lib;
import org.apache.jena.cmd.ArgDecl;
import org.apache.jena.cmd.CmdException;
@@ -36,6 +35,7 @@ import org.apache.jena.fuseki.main.cmds.ServerArgs;
import org.apache.jena.fuseki.main.sys.FusekiModule;
import org.apache.jena.fuseki.mgt.FusekiServerCtl;
import org.apache.jena.rdf.model.Model;
+import org.apache.shiro.lang.io.ResourceUtils;
import org.apache.shiro.web.servlet.ShiroFilter;
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
import org.eclipse.jetty.ee10.servlet.SessionHandler;
@@ -126,8 +126,12 @@ public class FMod_Shiro implements FusekiModule {
}
if ( shiroFile != null ) {
- IOX.checkReadableFile(shiroFile, FusekiConfigException::new);
- Filter filter = new FusekiShiroFilter(shiroFile);
+ // Shiro-style.
+ String shiroResourceName =
FusekiShiroLib.withResourcePrefix(shiroFile);
+ if ( ! ResourceUtils.resourceExists(shiroResourceName) )
+ throw new FusekiConfigException("Shiro resource does not
exist");
+ //IOX.checkReadableFile(shiroFile, FusekiConfigException::new);
+ Filter filter = new FusekiShiroFilter(shiroResourceName);
// This is a "before" filter.
serverBuilder.addFilter("/*", filter);
}
@@ -142,18 +146,19 @@ public class FMod_Shiro implements FusekiModule {
*/
private static class FusekiShiroFilter extends ShiroFilter {
- private final String shiroInitializationFile;
+ private final String shiroInitializationResource;
- FusekiShiroFilter(String filename) {
- shiroInitializationFile = IRILib.filenameToIRI(filename);
+ FusekiShiroFilter(String shiroResourceName) {
+ // Shiro file: URLs are "file:<no encoding>"
+ shiroInitializationResource = shiroResourceName;
}
@Override
public void init() throws Exception {
// Intercept Shiro initialization.
List<String> locations = List.of();
- if ( shiroInitializationFile != null ) {
- locations = List.of(shiroInitializationFile);
+ if ( shiroInitializationResource != null ) {
+ locations = List.of(shiroInitializationResource);
}
FusekiShiroLib.shiroEnvironment(getServletContext(), locations);
super.init();
diff --git
a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/shiro/FusekiShiroLib.java
b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/shiro/FusekiShiroLib.java
index a04b42589a..357f4c5171 100644
---
a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/shiro/FusekiShiroLib.java
+++
b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/shiro/FusekiShiroLib.java
@@ -23,9 +23,7 @@ import java.nio.file.Path;
import java.util.List;
import jakarta.servlet.ServletContext;
-import org.apache.jena.atlas.lib.IRILib;
import org.apache.jena.fuseki.FusekiConfigException;
-import org.apache.jena.rfc3986.URIScheme;
import org.apache.shiro.lang.io.ResourceUtils;
import org.apache.shiro.web.env.EnvironmentLoaderListener;
@@ -37,19 +35,28 @@ import org.apache.shiro.web.env.EnvironmentLoaderListener;
shiroListener.initEnvironment(servletContext);
} catch (org.apache.shiro.config.ConfigurationException ex) {
ShiroEnvironmentLoaderListener.shiroConfigLog.error("Failed to
initialize Shiro: "+ex.getMessage());
- throw new FusekiConfigException(ex.getMessage());
+ throw new FusekiConfigException(ex.getMessage(), ex);
}
}
- private static String fileSchemePrefix = URIScheme.FILE.getPrefix();
+ private static final String fileShiroPrefix = "file:";
+ private static final int fileShiroPrefixLength = fileShiroPrefix.length();
- /** Look for a Shiro ini file, returning the first found, or return null */
+ /**
+ * Look for a Shiro ini file, returning the first found, or return null.
+ * The input is a IRI ("file:" encoded for spaces etc).
+ * The returned resource will be "Shiro" style - starts "file:", "url:",
"classpath:"
+ * but no encoding of the path.
+ * In Shiro, no prefix causes it to use {@link
ServlectContext#getResourceAsStream}.
+ * <p>
+ * See {@link ResourceUtils#hasResourcePrefix} and {@link
ResourceUtils#getInputStreamForPath}.
+ */
static String huntForShiroIni(List<String> locations) {
for ( String loc : locations ) {
// If file:, look for that file.
- if ( loc.startsWith(fileSchemePrefix) ) {
- // Convert (back) to a filesystem path.
- String fn = IRILib.IRIToFilename(loc);
+ if ( loc.startsWith(fileShiroPrefix) ) {
+ // Shiro format resource name.
+ String fn = loc.substring(fileShiroPrefixLength);
Path p = Path.of(fn);
if ( Files.exists(p) )
return loc;
@@ -62,4 +69,22 @@ import org.apache.shiro.web.env.EnvironmentLoaderListener;
}
return null;
}
+
+ public static String withResourcePrefix(String shiroFileName) {
+ if ( shiroFileName.startsWith(fileShiroPrefix) )
+ return shiroFileName;
+ // How Shiro likes it. file:, unencoded filename.
+ return fileShiroPrefix+shiroFileName;
+ }
+
+ public static String removeResourcePrefix(String shiroFileResource) {
+ if ( shiroFileResource.startsWith(fileShiroPrefix) ) {
+ // Shiro format resource name.
+ // Convert (back) to a filesystem path.
+ String fn = shiroFileResource.substring(fileShiroPrefixLength);
+ return fn;
+ }
+ return shiroFileResource;
+ }
+
}
diff --git
a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/shiro/TestModShiro.java
b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/shiro/TestModShiro.java
index 3a740012a2..30b12be6ee 100644
---
a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/shiro/TestModShiro.java
+++
b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/shiro/TestModShiro.java
@@ -30,8 +30,10 @@ import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.apache.jena.atlas.lib.Lib;
import org.apache.jena.atlas.net.Host;
import org.apache.jena.atlas.web.HttpException;
+import org.apache.jena.fuseki.FusekiConfigException;
import org.apache.jena.fuseki.main.FusekiServer;
import org.apache.jena.fuseki.main.cmds.FusekiMain;
import org.apache.jena.fuseki.main.sys.FusekiModule;
@@ -79,11 +81,28 @@ public class TestModShiro {
/** Builder for a server with Shiro */
private FusekiServer.Builder serverBuilderWithShiro(String filename) {
- System.getProperties().setProperty(FusekiServerCtl.envFusekiShiro,
filename);
+ Lib.setenv(FusekiServerCtl.envFusekiShiro, filename);
FusekiModules modules = FusekiModules.create(FMod_Shiro.create());
- return FusekiServer.create()
- .port(0)
- .fusekiModules(modules);
+ return FusekiServer.create().port(0).fusekiModules(modules);
+ }
+
+ // Shiro resource naming is "file:<unencoded path>"
+ @Test public void access_shiro_file_1() {
+ String dsname = "/ds";
+ DatasetGraph dsg = DatasetGraphFactory.createTxnMem();
+ FusekiServer server = serverBuilderWithShiro("testing/Shiro/shiro
withSpaceInName.ini")
+ .add(dsname, dsg)
+ .build();
+ try { server.start(); }
+ finally { server.stop(); }
+ }
+
+ @Test public void access_shiro_file_2() {
+ String dsname = "/ds";
+ DatasetGraph dsg = DatasetGraphFactory.createTxnMem();
+ FusekiServer.Builder builder =
serverBuilderWithShiro("testing/Shiro/shiro-no-such-file.ini");
+ // Even if no datasets, it's an error - Shiro protects the whole
server.
+ assertThrows(FusekiConfigException.class, ()->builder.build());
}
@Test public void access_localhost() {
diff --git a/jena-fuseki2/jena-fuseki-main/testing/Shiro/shiro
withSpaceInName.ini b/jena-fuseki2/jena-fuseki-main/testing/Shiro/shiro
withSpaceInName.ini
new file mode 100644
index 0000000000..2b9cce0c48
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-main/testing/Shiro/shiro withSpaceInName.ini
@@ -0,0 +1,13 @@
+# Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0
+
+[main]
+localhostFilter = org.apache.jena.fuseki.authz.LocalhostFilter
+
+[users]
+admin=pw
+
+[roles]
+
+[urls]
+/local/** = localhostFilter
+/public/** = anon
diff --git a/jena-tdb1/src/test/java/org/apache/jena/tdb1/store/TestNodeId.java
b/jena-tdb1/src/test/java/org/apache/jena/tdb1/store/TestNodeId.java
index 8a23911667..6b611083cd 100644
--- a/jena-tdb1/src/test/java/org/apache/jena/tdb1/store/TestNodeId.java
+++ b/jena-tdb1/src/test/java/org/apache/jena/tdb1/store/TestNodeId.java
@@ -33,24 +33,24 @@ import org.junit.Test ;
public class TestNodeId
{
// @BeforeClass public static void beforeClass() {
-// // If running just this test suite, then this happenes before
SystemTDB initialization.
-// System.getProperties().setProperty("tdb:store.enableInlineLiterals",
"true") ;
+// // If running just this test suite, then this happens before
SystemTDB initialization.
+// Lib.setenv("tdb:store.enableInlineLiterals", "true") ;
// }
-
+
@Test public void nodeId_01()
{
NodeId nodeId = NodeId.create(37) ;
assertEquals(37L, nodeId.getId()) ;
}
-
+
@Test public void nodeId_02()
{
NodeId nodeId = NodeId.create(-1L) ;
assertEquals(-1L, nodeId.getId()) ;
}
-
+
// Inlines
-
+
@Test public void nodeId_int_01()
{ test("1", NodeFactoryExtra.parseNode("1")) ; }
@@ -65,71 +65,71 @@ public class TestNodeId
@Test public void nodeId_int_05()
{ test("-1", NodeFactoryExtra.parseNode("-1")) ; }
-
+
@Test public void nodeId_int_06()
{ test("-180", NodeFactoryExtra.parseNode("-180")) ; }
@Test public void nodeId_int_07()
{ test("01", NodeFactoryExtra.parseNode("1")) ; }
-
+
@Test public void nodeId_int_08()
{ test("+01", NodeFactoryExtra.parseNode("1")) ; }
-
+
@Test public void nodeId_int_09()
// More than Long.MAX_VALUE
{ test("92233720368547758070", (Node)null) ; }
// On the edge.
-
- static long X = 1L<<55 ; // Just too large
- static long Y = -((1L<<55) +1) ; // Just too small
-
+
+ static long X = 1L<<55 ; // Just too large
+ static long Y = -((1L<<55) +1) ; // Just too small
+
@Test public void nodeId_int_10()
{ test("\""+Long.toString(X)+"\"^^xsd:integer", (Node)null) ; }
@Test public void nodeId_int_11()
- {
+ {
Node n = NodeValue.makeInteger(X-1).asNode() ;
- test("\""+Long.toString(X-1)+"\"^^xsd:integer", n) ;
+ test("\""+Long.toString(X-1)+"\"^^xsd:integer", n) ;
}
@Test public void nodeId_int_12()
{ test("\""+Long.toString(Y)+"\"^^xsd:integer", (Node)null) ; }
@Test public void nodeId_int_13()
- {
+ {
Node n = NodeValue.makeInteger(Y+1).asNode() ;
- test("\""+Long.toString(Y+1)+"\"^^xsd:integer", n) ;
+ test("\""+Long.toString(Y+1)+"\"^^xsd:integer", n) ;
}
@Test public void nodeId_int_20()
{ test("'300'^^xsd:byte", (Node)null) ; }
-
+
@Test public void nodeId_decimal_1()
{ test("3.14", NodeFactoryExtra.parseNode("3.14")) ; }
@Test public void nodeId_decimal_2()
{ test("123456789.123456789", (Node)null) ; }
-
+
// Just this once, directly create the Node.
@Test public void nodeId_decimal_3()
{ test("12.89", NodeFactory.createLiteralDT("12.89",
XSDDatatype.XSDdecimal)) ; }
@Test public void nodeId_decimal_4()
{ test("-1.0", NodeFactoryExtra.parseNode("-1.0")) ; }
-
+
// This number has > 47 bits of value : 2412.80478192688
@Test public void nodeId_decimal_5()
{ test("2412.80478192688", (Node)null) ; }
-
+
// This number has > 47 bits of value : -2412.80478192688
@Test public void nodeId_decimal_6()
{ test("-2412.80478192688", (Node)null) ; }
@Test public void nodeId_decimal_7()
- { test("'0.00000001'^^xsd:decimal",
- NodeFactory.createLiteralDT("0.00000001", XSDDatatype.XSDdecimal))
;
+ { test("'0.00000001'^^xsd:decimal",
+ NodeFactory.createLiteralDT("0.00000001", XSDDatatype.XSDdecimal)) ;
}
@Test public void nodeId_decimal_8()
@@ -151,22 +151,22 @@ public class TestNodeId
@Test public void nodeId_dateTime_05()
{ test("'2008-04-28T15:36:15'^^xsd:dateTime") ; }
- // Note the trailing zero - system does not preserve perfect lexical
forms.
+ // Note the trailing zero - system does not preserve perfect lexical forms.
@Test public void nodeId_dateTime_06()
{ test("'2008-04-28T15:36:05.450'^^xsd:dateTime",
"'2008-04-28T15:36:05.45'^^xsd:dateTime") ; }
// Old Java bug, now fixed: T24:00:00 not accepted by JDK
DatatypeFactory.newXMLGregorianCalendar(lex)
- // Note the Jena value is an XSDDateTime so it retains the "24"/"00" next
day distinction.
+ // Note the Jena value is an XSDDateTime so it retains the "24"/"00" next
day distinction.
@Test public void nodeId_dateTime_07()
{ test("'2008-04-28T24:00:00'^^xsd:dateTime") ; }
-
+
// Out of range.
@Test public void nodeId_dateTime_08()
{ test("'8008-04-28T15:36:05.45'^^xsd:dateTime", (Node)null) ; }
@Test public void nodeId_dateTime_09()
{ test("'2008-04-28T15:36:05.001'^^xsd:dateTime") ; }
-
+
@Test public void nodeId_dateTime_10()
{ test("'2008-04-28T15:36:05.01'^^xsd:dateTime") ; }
@@ -230,7 +230,7 @@ public class TestNodeId
{ test("'0'^^xsd:boolean",
NodeFactoryExtra.parseNode("'false'^^xsd:boolean")) ; }
private void test(String x) { test(x, x) ; }
-
+
private void test(String x, String expected)
{
test(x, NodeFactoryExtra.parseNode(expected)) ;
@@ -244,7 +244,7 @@ public class TestNodeId
if ( nodeId != null )
assertTrue("Converted NodeId but datatype test was false", b) ;
-
+
if ( correct == null )
{
assertNull("Expected no encoding: got: "+nodeId, nodeId) ;
@@ -253,11 +253,11 @@ public class TestNodeId
assertNotNull("Expected inlining: "+n, nodeId) ;
Node n2 = NodeId.extract(nodeId) ;
assertNotNull("Expected recovery", n2) ;
-
+
String s =
"("+correct.getLiteralLexicalForm()+","+n2.getLiteralLexicalForm()+")" ;
-
+
assertTrue("Not same value: "+s, correct.sameValueAs(n2)) ;
-
+
// Term equality.
assertEquals("Not same term", correct, n2) ;
}