You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by ki...@apache.org on 2017/06/13 10:13:30 UTC

[3/6] jena git commit: Collating data via custom function

Collating data via custom function


Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/6e3be8d7
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/6e3be8d7
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/6e3be8d7

Branch: refs/heads/master
Commit: 6e3be8d728aca68010273080e804ef7fdaf2fd2a
Parents: 3e9a2de
Author: Bruno P. Kinoshita <br...@yahoo.com.br>
Authored: Sun Apr 30 01:54:40 2017 +1200
Committer: Bruno P. Kinoshita <br...@yahoo.com.br>
Committed: Sun Apr 30 13:25:00 2017 +1200

----------------------------------------------------------------------
 .../org/apache/jena/sparql/expr/NodeValue.java  | 24 +++++++-
 .../sparql/expr/nodevalue/NodeFunctions.java    |  5 ++
 .../sparql/expr/nodevalue/NodeValueString.java  | 16 ++++--
 .../jena/sparql/function/StandardFunctions.java |  3 +
 .../sparql/function/library/FN_Collation.java   | 59 ++++++++++++++++++++
 5 files changed, 100 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/6e3be8d7/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java
index c2b727e..47aef8d 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java
@@ -27,8 +27,10 @@ import java.io.FileInputStream ;
 import java.io.InputStream ;
 import java.math.BigDecimal ;
 import java.math.BigInteger ;
+import java.text.Collator;
 import java.util.Calendar ;
 import java.util.Iterator ;
+import java.util.Locale;
 import java.util.Properties ;
 import java.util.ServiceLoader ;
 
@@ -243,9 +245,13 @@ public abstract class NodeValue extends ExprNode
     public static NodeValue makeDouble(double d)
     { return new NodeValueDouble(d) ; }
 
-    public static NodeValue makeString(String s) 
+    public static NodeValue makeString(String s)
     { return new NodeValueString(s) ; }
 
+    // instead of changing makeString, we can add another method like makeCollatedString
+    public static NodeValue makeString(String s, String collation)
+    { return new NodeValueString(s, collation) ; }
+
     public static NodeValue makeLangString(String s, String lang) 
     { return new NodeValueLang(s, lang) ; }
 
@@ -750,7 +756,18 @@ public abstract class NodeValue extends ExprNode
             case VSPACE_NUM:        return XSDFuncOp.compareNumeric(nv1, nv2) ;
             case VSPACE_STRING:
             {
-                int cmp = XSDFuncOp.compareString(nv1, nv2) ;
+                // Not sure if this would fit in XSDFuncOp, maybe passing a locale string or Collator object
+                // to compareString
+                int cmp = 0;
+                String c1 = nv1.getCollation();
+                String c2 = nv2.getCollation();
+                if (c1 != null && c2 != null && c1.equals(c2)) {
+                    Locale desiredLocale = Locale.forLanguageTag(c1);
+                    Collator collator = Collator.getInstance(desiredLocale);
+                    cmp = collator.compare(nv1.getString(), nv2.getString());
+                } else {
+                    cmp = XSDFuncOp.compareString(nv1, nv2) ;
+                }
                 
                 // Split plain literals and xsd:strings for sorting purposes.
                 if ( ! sortOrderingCompare )
@@ -954,7 +971,8 @@ public abstract class NodeValue extends ExprNode
     public boolean     getBoolean()     { raise(new ExprEvalTypeException("Not a boolean: "+this)) ; return false ; }
     public String      getString()      { raise(new ExprEvalTypeException("Not a string: "+this)) ; return null ; }
     public String      getLang()        { raise(new ExprEvalTypeException("Not a string: "+this)) ; return null ; }
-    
+    public String      getCollation()   { raise(new ExprEvalTypeException("Not a collation: "+this)) ; return null ; }
+
     public BigInteger  getInteger()     { raise(new ExprEvalTypeException("Not an integer: "+this)) ; return null ; }
     public BigDecimal  getDecimal()     { raise(new ExprEvalTypeException("Not a decimal: "+this)) ; return null ; }
     public float       getFloat()       { raise(new ExprEvalTypeException("Not a float: "+this)) ; return Float.NaN ; }

http://git-wip-us.apache.org/repos/asf/jena/blob/6e3be8d7/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeFunctions.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeFunctions.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeFunctions.java
index 3aa8db3..1ad0c35 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeFunctions.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeFunctions.java
@@ -188,6 +188,11 @@ public class NodeFunctions {
         return NodeValue.makeString(str(nv.asNode())) ;
     }
 
+    // or instead or can create another utility method like strCollation(NodeValue, String)
+    public static NodeValue str(NodeValue nv, String collation) {
+        return NodeValue.makeString(str(nv.asNode()), collation) ;
+    }
+
     public static String str(Node node) {
         if ( node.isLiteral() )
             return node.getLiteral().getLexicalForm() ;

http://git-wip-us.apache.org/repos/asf/jena/blob/6e3be8d7/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueString.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueString.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueString.java
index a921c43..ac4377b 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueString.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueString.java
@@ -29,9 +29,14 @@ public class NodeValueString extends NodeValue
     // A plain string, with no language tag, or an xsd:string.
     
     private String string ; 
-    
-    public NodeValueString(String str)         { string = str ; } 
-    public NodeValueString(String str, Node n) { super(n) ; string = str ; }
+    // Here we are adding a new feature to a NodeValueString. Instead, we could try to create a new type
+    // that extends NodeValue. e.g. NodeValueCollatedString, moving this property and half constructors away
+    private final String collation;
+
+    public NodeValueString(String str)         { this(str, (String) null); }
+    public NodeValueString(String str, String collation)         { string = str ; this.collation = collation; }
+    public NodeValueString(String str, Node n) { this(str, n, (String) null); }
+    public NodeValueString(String str, Node n, String collation) { super(n) ; string = str ; this.collation = collation; }
     
     @Override
     public boolean isString() { return true ; }
@@ -41,7 +46,10 @@ public class NodeValueString extends NodeValue
 
     @Override
     public String asString() { return string ; }
-    
+
+    @Override
+    public String getCollation() { return collation ; }
+
     @Override
     public String toString()
     { 

http://git-wip-us.apache.org/repos/asf/jena/blob/6e3be8d7/jena-arq/src/main/java/org/apache/jena/sparql/function/StandardFunctions.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/function/StandardFunctions.java b/jena-arq/src/main/java/org/apache/jena/sparql/function/StandardFunctions.java
index db38377..145b1b0 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/function/StandardFunctions.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/function/StandardFunctions.java
@@ -95,6 +95,9 @@ public class StandardFunctions
         addCastTemporal(registry, XSDDatatype.XSDgMonthDay) ;
         addCastTemporal(registry, XSDDatatype.XSDgDay) ;
 
+        // Using ARQ prefix http://jena.apache.org/ARQ/function#
+        add(registry, ARQConstants.ARQFunctionLibraryURI+"collation",        FN_Collation.class) ;
+
         //TODO op:numeric-greater-than etc.
         //TODO sparql:* for all the SPARQL builtins.
         

http://git-wip-us.apache.org/repos/asf/jena/blob/6e3be8d7/jena-arq/src/main/java/org/apache/jena/sparql/function/library/FN_Collation.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/function/library/FN_Collation.java b/jena-arq/src/main/java/org/apache/jena/sparql/function/library/FN_Collation.java
new file mode 100644
index 0000000..639ee98
--- /dev/null
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/function/library/FN_Collation.java
@@ -0,0 +1,59 @@
+/*
+ * 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.function.library;
+
+import java.text.Collator;
+import java.util.Locale;
+
+import org.apache.jena.sparql.expr.NodeValue;
+import org.apache.jena.sparql.expr.nodevalue.NodeFunctions;
+import org.apache.jena.sparql.expr.nodevalue.NodeValueLang;
+import org.apache.jena.sparql.function.FunctionBase2;
+
+/**
+ * Collation function. Takes two parameters. First is the collation, second the
+ * Node, that is an {@link Expr} (ExprVar, ExprFunctionN, NodeValue, etc).
+ *
+ * <p>Called with a prefix @{code p}, e.g. {@code ORDER BY p:collation("fi", ?label);}.
+ * The first argument (in this case, "fi") is then resolved to a {@link Locale}, that is
+ * used to build a {@link Collator}. If a locale does not match any known collator, then
+ * a rule based collator ({@link RuleBasedCollator}) is returned, but with no rules,
+ * returning values in natural order, not applying any specific collation order.</p>
+ *
+ * <p>The second argument, which is an {@link Expr}, will have its literal string value
+ * extracted (or will raise an error if it is not possible). This means that if the
+ * expr is a {@link NodeValueLang} (e.g. rendered from "Casa"@pt), the language tag will
+ * be discarded, and only the literal string value (i.e. Casa) will be taken into account
+ * for this function.</p>
+ */
+public class FN_Collation extends FunctionBase2 {
+
+    public FN_Collation() {
+        super();
+    }
+
+    @Override
+    public NodeValue exec(NodeValue v1, NodeValue v2) {
+        // retrieve collation value
+        String collation = NodeFunctions.str(v1.asNode());
+        // return a NodeValue that contains the v2 literal string, plus the given collation
+        return NodeFunctions.str(v2, collation);
+    }
+
+}