Skip to content

Commit

Permalink
Towards JENA-632: Conversion of Nodes to JsonValues.
Browse files Browse the repository at this point in the history
  • Loading branch information
afs committed Mar 13, 2018
1 parent 6e20282 commit 2dd4418
Show file tree
Hide file tree
Showing 5 changed files with 199 additions and 4 deletions.
Expand Up @@ -26,6 +26,7 @@
import org.apache.jena.graph.NodeFactory;
import org.apache.jena.sparql.expr.ExprEvalException;
import org.apache.jena.sparql.expr.NodeValue;
import org.apache.jena.sparql.lib.RDFTerm2Json;

/**
* General representation of an {@link NodeValue} for JavaScript. Conversion is to native
Expand All @@ -34,6 +35,7 @@
*
* @see #fromNodeValue
* @see #toNodeValue
* @see RDFTerm2Json RDFTerm2Json, for one way conversion JSON.
*/

public class NV implements RDFJS {
Expand Down
104 changes: 104 additions & 0 deletions jena-arq/src/main/java/org/apache/jena/sparql/lib/RDFTerm2Json.java
@@ -0,0 +1,104 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.jena.sparql.lib;

import org.apache.jena.atlas.json.*;
import org.apache.jena.datatypes.RDFDatatype;
import org.apache.jena.graph.Node;
import org.apache.jena.rdf.model.impl.Util;
import org.apache.jena.riot.system.RiotLib;
import org.apache.jena.sparql.expr.NodeValue;
import org.apache.jena.sparql.function.js.NV;

/**
* General converting of {@link Node}s to JSON.
* <p>
* This is a one way, lossy, conversion from an RDF Term to the best available JSON value.
* <p>
* This is not SPARQL results in JSON ({@locde application/result-sets+json}).
*
* <table>
* <tr><th>RDF Term</th><th>JSON value</th></tr>
* <tr><td>URI</td><td>String</td></tr>
* <tr><td>xsd:string</td><td>String</td></tr>
* <tr><td>rdf:langString</td><td>String (no {@literal @}lang)</td></tr>
* <tr><td>XSD numeric</td><td>JSON number</td></tr>
* <tr><td>xsd:boolean</td><td>boolean</td></tr>
* <tr><td>Literal, other datatype</td><td>String, no ^^</td></tr>
* <tr><td>Unbound</td><td>JSON null</td></tr>
* </table>
*
* @see NV for conversion to and from {@link NodeValue}s for function argument and results.
*/

public class RDFTerm2Json {
// Six data types that are primitives in JavaScript:
// Boolean
// Null
// Undefined
// Number
// String
// Symbol (new in ECMAScript 6; not in Nashorn/Java8).
// and Object

public static JsonValue fromNode(Node node) {
if ( node == null )
return JsonNull.instance;
if ( node.isURI() )
return new JsonString(node.getURI());
if ( node.isBlank() ) {
Node node2 = RiotLib.blankNodeToIri(node);
return new JsonString(node.getURI());
}
if ( node.isVariable() )
return new JsonString("?"+node.getName());

// Literals.
if ( Util.isSimpleString(node) || Util.isLangString(node) )
return new JsonString(node.getLiteralLexicalForm());

// Includes well-formed testing.
RDFDatatype dt = node.getLiteralDatatype();

NodeValue nv = NodeValue.makeNode(node);
if ( nv.isNumber() ) {
// Order matters here to find the narrowest choice.
if ( nv.isInteger() ) {
try {
return JsonNumber.value(nv.getInteger().longValueExact());
} catch (ArithmeticException ex) {
// Bad in some way : scale maybe.
// Try as decimal.
}
}
if ( nv.isDecimal() )
return JsonNumber.value(nv.getDecimal());
if ( nv.isDouble() )
return JsonNumber.value(nv.getDouble());
if ( nv.isFloat() )
return JsonNumber.value(nv.getFloat());
// Drop through.
} else if ( nv.isBoolean() ) {
return new JsonBoolean(nv.getBoolean());
}

// else
return new JsonString(node.getLiteralLexicalForm());
}
}
Expand Up @@ -32,7 +32,7 @@ public class TestNV {

// No conversion to JS - becomes an NV.
@Test public void nv_5() { test("'2018-01-06T17:56:41.293+00:00'^^xsd:dateTime"); }
@Test public void nv_6() { test("<http://jena/apche.org/>"); }
@Test public void nv_6() { test("<http://jena.apache.org/>"); }
@Test public void nv_7() { test("_:abc123"); }

@Test public void nv_10() {
Expand All @@ -44,10 +44,10 @@ public class TestNV {
}

@Test public void nv_12() {
NodeValue nodeValue = nv("<http://jena/apche.org/>");
NodeValue nodeValue = nv("<http://jena.apache.org/>");
NV nv = new NV(nodeValue);
assertEquals("http://jena/apche.org/", nv.getUri());
assertEquals("http://jena/apche.org/", nv.getValue());
assertEquals("http://jena.apache.org/", nv.getUri());
assertEquals("http://jena.apache.org/", nv.getValue());
assertEquals("NamedNode", nv.getTermType());
}

Expand Down
31 changes: 31 additions & 0 deletions jena-arq/src/test/java/org/apache/jena/sparql/lib/TS_Lib.java
@@ -0,0 +1,31 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.jena.sparql.lib;

import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

@RunWith(Suite.class)
@SuiteClasses( {
TestRDFTerm2Json.class
})
public class TS_Lib {

}
@@ -0,0 +1,58 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.jena.sparql.lib;

import static org.junit.Assert.assertEquals;

import java.math.BigDecimal;

import org.apache.jena.atlas.json.*;
import org.apache.jena.graph.Node;
import org.apache.jena.sparql.lib.RDFTerm2Json;
import org.apache.jena.sparql.sse.SSE;
import org.junit.Test;

public class TestRDFTerm2Json {

@Test public void n2j_1() { test("'abc'", new JsonString("abc")); }

@Test public void n2j_2() { test("<http://jena.apache.org/>", new JsonString("http://jena.apache.org/")); }

@Test public void n2j_3() { test("123", JsonNumber.value(123)); }

@Test public void n2j_4() { test("123.0", JsonNumber.value(new BigDecimal("123.0"))); }

@Test public void n2j_5() { test("123e0", JsonNumber.value(/*(double)*/123e0)); }

@Test public void n2j_6() { test("'123e0'^^xsd:float", JsonNumber.value((float)123.0)); }

@Test public void n2j_7() { test("true", new JsonBoolean(true)); }

@Test public void n2j_8() { test("'text'@en", new JsonString("text")) ; }

@Test public void n2j_9() { assertEquals(JsonNull.instance, RDFTerm2Json.fromNode(null)) ; }


private void test(String nodeStr, JsonValue expected) {
Node n = SSE.parseNode(nodeStr);
JsonValue jv = RDFTerm2Json.fromNode(n);
assertEquals(expected, jv);
}

}

0 comments on commit 2dd4418

Please sign in to comment.