You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@marmotta.apache.org by ja...@apache.org on 2013/02/21 12:23:28 UTC

[8/19] MARMOTTA-104: renamed packages in ldpath (resolved)

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5b8766b3/libraries/ldpath/ldpath-functions-html/src/main/java/at/newmedialab/ldpath/model/functions/CssSelectFunction.java
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-html/src/main/java/at/newmedialab/ldpath/model/functions/CssSelectFunction.java b/libraries/ldpath/ldpath-functions-html/src/main/java/at/newmedialab/ldpath/model/functions/CssSelectFunction.java
deleted file mode 100644
index 78d6462..0000000
--- a/libraries/ldpath/ldpath-functions-html/src/main/java/at/newmedialab/ldpath/model/functions/CssSelectFunction.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/**
- * Copyright (C) 2013 Salzburg Research.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package at.newmedialab.ldpath.model.functions;
-
-import at.newmedialab.ldpath.api.backend.RDFBackend;
-import at.newmedialab.ldpath.api.functions.SelectorFunction;
-import at.newmedialab.ldpath.model.transformers.StringTransformer;
-import org.jsoup.Jsoup;
-import org.jsoup.nodes.Document;
-import org.jsoup.nodes.Element;
-import org.jsoup.select.Selector.SelectorParseException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-
-public class CssSelectFunction<KiWiNode> extends SelectorFunction<KiWiNode> {
-
-    private Logger log = LoggerFactory.getLogger(CssSelectFunction.class);
-
-    private final StringTransformer<KiWiNode> transformer = new StringTransformer<KiWiNode>();
-
-    /**
-     * Apply the function to the list of nodes passed as arguments and return the result as type T.
-     * Throws IllegalArgumentException if the function cannot be applied to the nodes passed as
-     * argument
-     * or the number of arguments is not correct.
-     *
-     * @param args a nested list of KiWiNodes
-     * @return
-     */
-    @Override
-    public Collection<KiWiNode> apply(RDFBackend<KiWiNode> rdfBackend, KiWiNode context, Collection<KiWiNode>... args)
-            throws IllegalArgumentException {
-        if (args.length < 1) {
-            throw new IllegalArgumentException("CSS-Selector is required as first argument.");
-        }
-        Set<String> jsoupSelectors = new HashSet<String>();
-        for (KiWiNode xpath : args[0]) {
-            try {
-                jsoupSelectors.add(transformer.transform(rdfBackend, xpath));
-            } catch (IllegalArgumentException iae) {
-                throw new IllegalArgumentException("First argument must not contain anything else than String-Literals!");
-            }
-        }
-        Iterator<KiWiNode> it;
-        if (args.length < 2) {
-            log.debug("Use context {} to apply css-selector {}", context, jsoupSelectors);
-            it = Collections.singleton(context).iterator();
-        } else {
-            log.debug("apply css-selector {} on parsed parameters", jsoupSelectors);
-            it = at.newmedialab.ldpath.util.Collections.iterator(1, args);
-        }
-        List<KiWiNode> result = new ArrayList<KiWiNode>();
-        while (it.hasNext()) {
-            KiWiNode n = it.next();
-            try {
-                final String string = transformer.transform(rdfBackend, n);
-                final Document jsoup = Jsoup.parse(string);
-                if (rdfBackend.isURI(context)) {
-                    jsoup.setBaseUri(rdfBackend.stringValue(context));
-                }
-                for (String r : doFilter(jsoup, jsoupSelectors)) {
-                    result.add(rdfBackend.createLiteral(r));
-                }
-            } catch (IOException e) {
-                // This should never happen, since validation is turned off.
-            }
-        }
-
-        return result;
-    }
-
-    private LinkedList<String> doFilter(Document jsoup, Set<String> jsoupSelectors) throws IOException {
-        LinkedList<String> result = new LinkedList<String>();
-        for (String jsoupSel : jsoupSelectors) {
-            try {
-                for (Element e : jsoup.select(jsoupSel)) {
-                    result.add(e.outerHtml());
-                }
-            } catch (SelectorParseException xpe) {
-                throw new IllegalArgumentException("error while processing jsoup selector: '" + jsoupSel + "'", xpe);
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Return the name of the NodeFunction for registration in the function registry
-     *
-     * @return
-     * @param backend
-     */
-    @Override
-    public String getLocalName() {
-        return "css";
-    }
-
-    /**
-     * A string describing the signature of this node function, e.g.
-     * "fn:content(uris : Nodes) : Nodes". The
-     * syntax for representing the signature can be chosen by the implementer. This method is for
-     * informational
-     * purposes only.
-     *
-     * @return
-     */
-    @Override
-    public String getSignature() {
-        return "fn:css(jsoup: String [, nodes: XMLLiteralList]) : LiteralList";
-    }
-
-    /**
-     * A short human-readable description of what the node function does.
-     *
-     * @return
-     */
-    @Override
-    public String getDescription() {
-        return "Evaluate an JSoup CSS selector on either the value of the context node or the values of the nodes passed as arguments.";
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5b8766b3/libraries/ldpath/ldpath-functions-html/src/main/java/org/apache/marmotta/ldpath/model/functions/html/CleanHtmlFunction.java
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-html/src/main/java/org/apache/marmotta/ldpath/model/functions/html/CleanHtmlFunction.java b/libraries/ldpath/ldpath-functions-html/src/main/java/org/apache/marmotta/ldpath/model/functions/html/CleanHtmlFunction.java
new file mode 100644
index 0000000..ed008b6
--- /dev/null
+++ b/libraries/ldpath/ldpath-functions-html/src/main/java/org/apache/marmotta/ldpath/model/functions/html/CleanHtmlFunction.java
@@ -0,0 +1,106 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.ldpath.model.functions.html;
+
+
+import org.apache.marmotta.ldpath.api.backend.RDFBackend;
+import org.apache.marmotta.ldpath.api.functions.SelectorFunction;
+import org.apache.marmotta.ldpath.model.transformers.StringTransformer;
+import org.apache.marmotta.ldpath.util.Collections;
+import org.jsoup.Jsoup;
+import org.jsoup.safety.Whitelist;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Function to clean up HTML and remove all script and style elements from the content.
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class CleanHtmlFunction<Node> extends SelectorFunction<Node> {
+
+    private final StringTransformer<Node> transformer = new StringTransformer<Node>();
+
+    private Logger log = LoggerFactory.getLogger(CleanHtmlFunction.class);
+
+    public CleanHtmlFunction() {
+    }
+
+    /**
+     * Apply the function to the list of nodes passed as arguments and return the result as type T.
+     * Throws IllegalArgumentException if the function cannot be applied to the nodes passed as argument
+     * or the number of arguments is not correct.
+     *
+     * @param args a list of KiWiNodes
+     * @return
+     */
+    @Override
+    public Collection<Node> apply(RDFBackend<Node> backend, Node context, Collection<Node>... args) throws IllegalArgumentException {
+        Iterator<Node> it;
+        if(args.length < 1){
+            log.debug("clean HTML from context {}",context);
+            it = java.util.Collections.singleton(context).iterator();
+        } else {
+            log.debug("clean HTML from parameters");
+            it = Collections.iterator(args);
+        }
+        List<Node> result = new ArrayList<Node>();
+        while(it.hasNext()) {
+            Node node = it.next();
+            String cleaned = Jsoup.clean(transformer.transform(backend, node), Whitelist.basic());
+            result.add(backend.createLiteral(cleaned));
+        }
+        return result;
+    }
+
+    /**
+     * Return the name of the NodeFunction for registration in the function registry
+     *
+     * @return
+     * @param backend
+     */
+    @Override
+    public String getLocalName() {
+        return "cleanHtml";
+    }
+
+    /**
+     * A string describing the signature of this node function, e.g. "fn:content(uris : Nodes) : Nodes". The
+     * syntax for representing the signature can be chosen by the implementer. This method is for informational
+     * purposes only.
+     *
+     * @return
+     */
+    @Override
+    public String getSignature() {
+        return "fn:cleanHtml(content: LiteralList) : LiteralList";
+    }
+
+    /**
+     * A short human-readable description of what the node function does.
+     *
+     * @return
+     */
+    @Override
+    public String getDescription() {
+        return "Function to clean up HTML and remove all script and style elements from the content. Can be used in-path, using the current context nodes as argument.";
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5b8766b3/libraries/ldpath/ldpath-functions-html/src/main/java/org/apache/marmotta/ldpath/model/functions/html/CssSelectFunction.java
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-html/src/main/java/org/apache/marmotta/ldpath/model/functions/html/CssSelectFunction.java b/libraries/ldpath/ldpath-functions-html/src/main/java/org/apache/marmotta/ldpath/model/functions/html/CssSelectFunction.java
new file mode 100644
index 0000000..fe58f2a
--- /dev/null
+++ b/libraries/ldpath/ldpath-functions-html/src/main/java/org/apache/marmotta/ldpath/model/functions/html/CssSelectFunction.java
@@ -0,0 +1,145 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.ldpath.model.functions.html;
+
+
+import org.apache.marmotta.ldpath.api.backend.RDFBackend;
+import org.apache.marmotta.ldpath.api.functions.SelectorFunction;
+import org.apache.marmotta.ldpath.model.transformers.StringTransformer;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Selector.SelectorParseException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+public class CssSelectFunction<KiWiNode> extends SelectorFunction<KiWiNode> {
+
+    private Logger log = LoggerFactory.getLogger(CssSelectFunction.class);
+
+    private final StringTransformer<KiWiNode> transformer = new StringTransformer<KiWiNode>();
+
+    /**
+     * Apply the function to the list of nodes passed as arguments and return the result as type T.
+     * Throws IllegalArgumentException if the function cannot be applied to the nodes passed as
+     * argument
+     * or the number of arguments is not correct.
+     *
+     * @param args a nested list of KiWiNodes
+     * @return
+     */
+    @Override
+    public Collection<KiWiNode> apply(RDFBackend<KiWiNode> rdfBackend, KiWiNode context, Collection<KiWiNode>... args)
+            throws IllegalArgumentException {
+        if (args.length < 1) {
+            throw new IllegalArgumentException("CSS-Selector is required as first argument.");
+        }
+        Set<String> jsoupSelectors = new HashSet<String>();
+        for (KiWiNode xpath : args[0]) {
+            try {
+                jsoupSelectors.add(transformer.transform(rdfBackend, xpath));
+            } catch (IllegalArgumentException iae) {
+                throw new IllegalArgumentException("First argument must not contain anything else than String-Literals!");
+            }
+        }
+        Iterator<KiWiNode> it;
+        if (args.length < 2) {
+            log.debug("Use context {} to apply css-selector {}", context, jsoupSelectors);
+            it = Collections.singleton(context).iterator();
+        } else {
+            log.debug("apply css-selector {} on parsed parameters", jsoupSelectors);
+            it = org.apache.marmotta.ldpath.util.Collections.iterator(1, args);
+        }
+        List<KiWiNode> result = new ArrayList<KiWiNode>();
+        while (it.hasNext()) {
+            KiWiNode n = it.next();
+            try {
+                final String string = transformer.transform(rdfBackend, n);
+                final Document jsoup = Jsoup.parse(string);
+                if (rdfBackend.isURI(context)) {
+                    jsoup.setBaseUri(rdfBackend.stringValue(context));
+                }
+                for (String r : doFilter(jsoup, jsoupSelectors)) {
+                    result.add(rdfBackend.createLiteral(r));
+                }
+            } catch (IOException e) {
+                // This should never happen, since validation is turned off.
+            }
+        }
+
+        return result;
+    }
+
+    private LinkedList<String> doFilter(Document jsoup, Set<String> jsoupSelectors) throws IOException {
+        LinkedList<String> result = new LinkedList<String>();
+        for (String jsoupSel : jsoupSelectors) {
+            try {
+                for (Element e : jsoup.select(jsoupSel)) {
+                    result.add(e.outerHtml());
+                }
+            } catch (SelectorParseException xpe) {
+                throw new IllegalArgumentException("error while processing jsoup selector: '" + jsoupSel + "'", xpe);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Return the name of the NodeFunction for registration in the function registry
+     *
+     * @return
+     * @param backend
+     */
+    @Override
+    public String getLocalName() {
+        return "css";
+    }
+
+    /**
+     * A string describing the signature of this node function, e.g.
+     * "fn:content(uris : Nodes) : Nodes". The
+     * syntax for representing the signature can be chosen by the implementer. This method is for
+     * informational
+     * purposes only.
+     *
+     * @return
+     */
+    @Override
+    public String getSignature() {
+        return "fn:css(jsoup: String [, nodes: XMLLiteralList]) : LiteralList";
+    }
+
+    /**
+     * A short human-readable description of what the node function does.
+     *
+     * @return
+     */
+    @Override
+    public String getDescription() {
+        return "Evaluate an JSoup CSS selector on either the value of the context node or the values of the nodes passed as arguments.";
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5b8766b3/libraries/ldpath/ldpath-functions-html/src/main/resources/META-INF/services/at.newmedialab.ldpath.api.functions.SelectorFunction
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-html/src/main/resources/META-INF/services/at.newmedialab.ldpath.api.functions.SelectorFunction b/libraries/ldpath/ldpath-functions-html/src/main/resources/META-INF/services/at.newmedialab.ldpath.api.functions.SelectorFunction
deleted file mode 100644
index 4c18e2a..0000000
--- a/libraries/ldpath/ldpath-functions-html/src/main/resources/META-INF/services/at.newmedialab.ldpath.api.functions.SelectorFunction
+++ /dev/null
@@ -1,2 +0,0 @@
-at.newmedialab.ldpath.model.functions.CleanHtmlFunction
-at.newmedialab.ldpath.model.functions.CssSelectFunction
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5b8766b3/libraries/ldpath/ldpath-functions-html/src/main/resources/META-INF/services/org.apache.marmotta.ldpath.api.functions.SelectorFunction
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-html/src/main/resources/META-INF/services/org.apache.marmotta.ldpath.api.functions.SelectorFunction b/libraries/ldpath/ldpath-functions-html/src/main/resources/META-INF/services/org.apache.marmotta.ldpath.api.functions.SelectorFunction
new file mode 100644
index 0000000..63e3080
--- /dev/null
+++ b/libraries/ldpath/ldpath-functions-html/src/main/resources/META-INF/services/org.apache.marmotta.ldpath.api.functions.SelectorFunction
@@ -0,0 +1,2 @@
+org.apache.marmotta.ldpath.model.functions.html.CleanHtmlFunction
+org.apache.marmotta.ldpath.model.functions.html.CssSelectFunction
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5b8766b3/libraries/ldpath/ldpath-functions-html/src/test/java/html/HtmlFunctionsTest.java
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-html/src/test/java/html/HtmlFunctionsTest.java b/libraries/ldpath/ldpath-functions-html/src/test/java/html/HtmlFunctionsTest.java
deleted file mode 100644
index 27b06dc..0000000
--- a/libraries/ldpath/ldpath-functions-html/src/test/java/html/HtmlFunctionsTest.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2013 Salzburg Research.
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package html;
-
-import at.newmedialab.ldpath.model.fields.FieldMapping;
-import at.newmedialab.ldpath.parser.ParseException;
-import at.newmedialab.ldpath.parser.RdfPathParser;
-import core.AbstractTestBase;
-import org.hamcrest.CoreMatchers;
-import org.junit.Before;
-import org.junit.Test;
-import org.openrdf.model.URI;
-import org.openrdf.model.Value;
-import org.openrdf.repository.RepositoryException;
-import org.openrdf.rio.RDFFormat;
-import org.openrdf.rio.RDFParseException;
-
-import java.io.IOException;
-import java.util.Collection;
-
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.hamcrest.CoreMatchers.not;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-
-public class HtmlFunctionsTest extends AbstractTestBase {
-
-    @Before
-    public void loadData() throws RepositoryException, RDFParseException, IOException {
-        super.loadData("data.n3", RDFFormat.N3);
-    }
-
-    @Test
-    public void testCleanHtmlFunction() throws ParseException {
-        URI uri = repository.getValueFactory().createURI(NSS.get("ex") + "Simple");
-
-        final RdfPathParser<Value> parser = createParserFromString("fn:cleanHtml(foo:html) :: xsd:string");
-        final FieldMapping<Object, Value> rule = parser.parseRule(NSS);
-
-        final Collection<Object> result = rule.getValues(backend, uri);
-        assertEquals(1, result.size());
-        final String txt = result.iterator().next().toString();
-
-        assertThat("attribute: id", txt, not(containsString("id=\"")));
-        assertThat("element: h1", txt, not(containsString("<h1>")));
-        assertThat("element: div", txt, not(containsString("<div>")));
-        assertThat("element: p", txt, containsString("<p>"));
-    }
-
-    @Test
-    public void testCssSelectFunction() throws ParseException {
-        URI uri = repository.getValueFactory().createURI(NSS.get("ex") + "Simple");
-
-        final RdfPathParser<Value> parser = createParserFromString("fn:css(\"p\", foo:html) :: xsd:string");
-        final FieldMapping<Object, Value> rule = parser.parseRule(NSS);
-
-        final Collection<Object> result = rule.getValues(backend, uri);
-        assertEquals(3, result.size());
-
-        for (Object object : result) {
-            String s = object.toString();
-            assertThat("String start", s, CoreMatchers.startsWith("<p"));
-            assertThat("String end", s, CoreMatchers.endsWith("</p>"));
-        }
-
-        final RdfPathParser<Value> parser2 = createParserFromString("fn:css(\"p#p2\", foo:html) :: xsd:string");
-        final FieldMapping<Object, Value> rule2 = parser2.parseRule(NSS);
-
-        final Collection<Object> result2 = rule2.getValues(backend, uri);
-        assertEquals(1, result2.size());
-
-        String txt = result2.iterator().next().toString();
-        assertThat(txt, CoreMatchers.containsString("Most marmots are highly social and use loud whistles to communicate with one another"));
-
-    }
-
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5b8766b3/libraries/ldpath/ldpath-functions-html/src/test/java/org/apache/marmotta/ldpath/model/functions/html/HtmlFunctionsTest.java
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-html/src/test/java/org/apache/marmotta/ldpath/model/functions/html/HtmlFunctionsTest.java b/libraries/ldpath/ldpath-functions-html/src/test/java/org/apache/marmotta/ldpath/model/functions/html/HtmlFunctionsTest.java
new file mode 100644
index 0000000..81937c3
--- /dev/null
+++ b/libraries/ldpath/ldpath-functions-html/src/test/java/org/apache/marmotta/ldpath/model/functions/html/HtmlFunctionsTest.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2013 Salzburg Research.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.marmotta.ldpath.model.functions.html;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.not;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import org.apache.marmotta.ldpath.model.fields.FieldMapping;
+import org.apache.marmotta.ldpath.parser.ParseException;
+import org.apache.marmotta.ldpath.parser.RdfPathParser;
+import org.apache.marmotta.ldpath.test.AbstractTestBase;
+import org.hamcrest.CoreMatchers;
+import org.junit.Before;
+import org.junit.Test;
+import org.openrdf.model.URI;
+import org.openrdf.model.Value;
+import org.openrdf.repository.RepositoryException;
+import org.openrdf.rio.RDFFormat;
+import org.openrdf.rio.RDFParseException;
+
+
+public class HtmlFunctionsTest extends AbstractTestBase {
+
+    @Before
+    public void loadData() throws RepositoryException, RDFParseException, IOException {
+        super.loadData("data.n3", RDFFormat.N3);
+    }
+
+    @Test
+    public void testCleanHtmlFunction() throws ParseException {
+        URI uri = repository.getValueFactory().createURI(NSS.get("ex") + "Simple");
+
+        final RdfPathParser<Value> parser = createParserFromString("fn:cleanHtml(foo:html) :: xsd:string");
+        final FieldMapping<Object, Value> rule = parser.parseRule(NSS);
+
+        final Collection<Object> result = rule.getValues(backend, uri);
+        assertEquals(1, result.size());
+        final String txt = result.iterator().next().toString();
+
+        assertThat("attribute: id", txt, not(containsString("id=\"")));
+        assertThat("element: h1", txt, not(containsString("<h1>")));
+        assertThat("element: div", txt, not(containsString("<div>")));
+        assertThat("element: p", txt, containsString("<p>"));
+    }
+
+    @Test
+    public void testCssSelectFunction() throws ParseException {
+        URI uri = repository.getValueFactory().createURI(NSS.get("ex") + "Simple");
+
+        final RdfPathParser<Value> parser = createParserFromString("fn:css(\"p\", foo:html) :: xsd:string");
+        final FieldMapping<Object, Value> rule = parser.parseRule(NSS);
+
+        final Collection<Object> result = rule.getValues(backend, uri);
+        assertEquals(3, result.size());
+
+        for (Object object : result) {
+            String s = object.toString();
+            assertThat("String start", s, CoreMatchers.startsWith("<p"));
+            assertThat("String end", s, CoreMatchers.endsWith("</p>"));
+        }
+
+        final RdfPathParser<Value> parser2 = createParserFromString("fn:css(\"p#p2\", foo:html) :: xsd:string");
+        final FieldMapping<Object, Value> rule2 = parser2.parseRule(NSS);
+
+        final Collection<Object> result2 = rule2.getValues(backend, uri);
+        assertEquals(1, result2.size());
+
+        String txt = result2.iterator().next().toString();
+        assertThat(txt, CoreMatchers.containsString("Most marmots are highly social and use loud whistles to communicate with one another"));
+
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5b8766b3/libraries/ldpath/ldpath-functions-html/src/test/resources/html/data.n3
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-html/src/test/resources/html/data.n3 b/libraries/ldpath/ldpath-functions-html/src/test/resources/html/data.n3
deleted file mode 100644
index 7154cba..0000000
--- a/libraries/ldpath/ldpath-functions-html/src/test/resources/html/data.n3
+++ /dev/null
@@ -1,19 +0,0 @@
-@prefix ex: <http://www.example.com/> .
-@prefix foo: <http://localhost/vcab#> .
-
-ex:Simple a ex:HtmlTest;
-	foo:html	"""<!DOCTYPE html>
-<html>
-  <head>
-  </head>
-  <body>
-  <h1>Marmotta</h1>
-  <div>Marmotta, italian for "Marmot"</div>
-  <div id="abstract">
-    <p id="p1">Marmots are generally large ground squirrels in the genus Marmota, of which there are 15 species. Those most often referred to as marmots tend to live in mountainous areas, such as the Alps, northern Apennines, Eurasian steppes, Carpathians, Tatras, and Pyrenees in Europe and northwestern Asia; the Rocky Mountains, Black Hills, Cascades, and Sierra Nevada in North America; and the Deosai Plateau in Pakistan and Ladakh in India. The groundhog, however, is also sometimes called a marmot, while the similarly sized, but more social, prairie dog is not classified in the genus Marmota but in the related genus Cynomys.</p>
-    <p id="p2">Marmots typically live in burrows (often within rockpiles, particularly in the case of the yellow-bellied marmot), and hibernate there through the winter. Most marmots are highly social and use loud whistles to communicate with one another, especially when alarmed.</p>
-    <p id="p3">Marmots mainly eat greens and many types of grasses, berries, lichens, mosses, roots and flowers.</p>
-  </div>
-  </body>
-</html>
-""".

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5b8766b3/libraries/ldpath/ldpath-functions-html/src/test/resources/org/apache/marmotta/ldpath/model/functions/html/data.n3
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-html/src/test/resources/org/apache/marmotta/ldpath/model/functions/html/data.n3 b/libraries/ldpath/ldpath-functions-html/src/test/resources/org/apache/marmotta/ldpath/model/functions/html/data.n3
new file mode 100644
index 0000000..7154cba
--- /dev/null
+++ b/libraries/ldpath/ldpath-functions-html/src/test/resources/org/apache/marmotta/ldpath/model/functions/html/data.n3
@@ -0,0 +1,19 @@
+@prefix ex: <http://www.example.com/> .
+@prefix foo: <http://localhost/vcab#> .
+
+ex:Simple a ex:HtmlTest;
+	foo:html	"""<!DOCTYPE html>
+<html>
+  <head>
+  </head>
+  <body>
+  <h1>Marmotta</h1>
+  <div>Marmotta, italian for "Marmot"</div>
+  <div id="abstract">
+    <p id="p1">Marmots are generally large ground squirrels in the genus Marmota, of which there are 15 species. Those most often referred to as marmots tend to live in mountainous areas, such as the Alps, northern Apennines, Eurasian steppes, Carpathians, Tatras, and Pyrenees in Europe and northwestern Asia; the Rocky Mountains, Black Hills, Cascades, and Sierra Nevada in North America; and the Deosai Plateau in Pakistan and Ladakh in India. The groundhog, however, is also sometimes called a marmot, while the similarly sized, but more social, prairie dog is not classified in the genus Marmota but in the related genus Cynomys.</p>
+    <p id="p2">Marmots typically live in burrows (often within rockpiles, particularly in the case of the yellow-bellied marmot), and hibernate there through the winter. Most marmots are highly social and use loud whistles to communicate with one another, especially when alarmed.</p>
+    <p id="p3">Marmots mainly eat greens and many types of grasses, berries, lichens, mosses, roots and flowers.</p>
+  </div>
+  </body>
+</html>
+""".

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5b8766b3/libraries/ldpath/ldpath-functions-math/pom.xml
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-math/pom.xml b/libraries/ldpath/ldpath-functions-math/pom.xml
index de14966..401ca9e 100644
--- a/libraries/ldpath/ldpath-functions-math/pom.xml
+++ b/libraries/ldpath/ldpath-functions-math/pom.xml
@@ -77,7 +77,7 @@
                         <!-- Enable this for including your enhancement chain configuration -->
                         <!-- <Install-Path>config</Install-Path> -->
                         <Export-Package>
-                            at.newmedialab.ldpath.model.*;version=${project.version},
+                            org.apache.marmotta.ldpath.model.*;version=${project.version},
                         </Export-Package>
                         <_include>src/main/resources/META-INF/MANIFEST.MF</_include>
                     </instructions>

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5b8766b3/libraries/ldpath/ldpath-functions-math/src/main/java/at/newmedialab/ldpath/model/functions/math/MathFunction.java
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-math/src/main/java/at/newmedialab/ldpath/model/functions/math/MathFunction.java b/libraries/ldpath/ldpath-functions-math/src/main/java/at/newmedialab/ldpath/model/functions/math/MathFunction.java
deleted file mode 100644
index df450e0..0000000
--- a/libraries/ldpath/ldpath-functions-math/src/main/java/at/newmedialab/ldpath/model/functions/math/MathFunction.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- * Copyright (C) 2013 Salzburg Research.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package at.newmedialab.ldpath.model.functions.math;
-
-
-import at.newmedialab.ldpath.api.functions.SelectorFunction;
-
-public abstract class MathFunction<Node> extends SelectorFunction<Node> {
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5b8766b3/libraries/ldpath/ldpath-functions-math/src/main/java/at/newmedialab/ldpath/model/functions/math/MaxFunction.java
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-math/src/main/java/at/newmedialab/ldpath/model/functions/math/MaxFunction.java b/libraries/ldpath/ldpath-functions-math/src/main/java/at/newmedialab/ldpath/model/functions/math/MaxFunction.java
deleted file mode 100644
index 8a288f2..0000000
--- a/libraries/ldpath/ldpath-functions-math/src/main/java/at/newmedialab/ldpath/model/functions/math/MaxFunction.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * Copyright (C) 2013 Salzburg Research.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package at.newmedialab.ldpath.model.functions.math;
-
-import at.newmedialab.ldpath.api.backend.RDFBackend;
-import at.newmedialab.ldpath.model.Constants;
-import at.newmedialab.ldpath.model.transformers.DoubleTransformer;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Collection;
-
-public class MaxFunction<Node> extends MathFunction<Node> {
-
-    protected final DoubleTransformer<Node> doubleTransformer = new DoubleTransformer<Node>();
-    protected final URI doubleType = URI.create(Constants.NS_XSD + "double");
-
-    @Override
-    public Collection<Node> apply(RDFBackend<Node> backend, Node context,
-            Collection<Node>... args) throws IllegalArgumentException {
-
-        ArrayList<Node> result = new ArrayList<Node>();
-        for (Collection<Node> arg : args) {
-            Node res = calc(backend, arg);
-            if (res != null) {
-                result.add(res);
-            }
-        }
-        return result;
-    }
-
-    protected Node calc(RDFBackend<Node> backend, Collection<Node> arg) {
-        /* MAX */
-        double d = Double.MIN_VALUE;
-        Node max = null;
-        for (Node n : arg) {
-            try {
-                Double val = doubleTransformer.transform(backend, n);
-                if (val > d) {
-                    d = val;
-                    max = n;
-                }
-            } catch (IllegalArgumentException e) {
-                // we just ignore non-numeric nodes
-            }
-        }
-
-        return max;
-    }
-
-    @Override
-    public String getDescription() {
-        return "select the max of each argument";
-    }
-
-    @Override
-    public String getSignature() {
-        return "fn:max(LiteralList l [, ...]) :: NumberLiteral(s)";
-    }
-
-    @Override
-    public String getLocalName() {
-        return "max";
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5b8766b3/libraries/ldpath/ldpath-functions-math/src/main/java/at/newmedialab/ldpath/model/functions/math/MinFunction.java
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-math/src/main/java/at/newmedialab/ldpath/model/functions/math/MinFunction.java b/libraries/ldpath/ldpath-functions-math/src/main/java/at/newmedialab/ldpath/model/functions/math/MinFunction.java
deleted file mode 100644
index faf7b3a..0000000
--- a/libraries/ldpath/ldpath-functions-math/src/main/java/at/newmedialab/ldpath/model/functions/math/MinFunction.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * Copyright (C) 2013 Salzburg Research.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package at.newmedialab.ldpath.model.functions.math;
-
-import at.newmedialab.ldpath.api.backend.RDFBackend;
-import at.newmedialab.ldpath.model.Constants;
-import at.newmedialab.ldpath.model.transformers.DoubleTransformer;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Collection;
-
-public class MinFunction<Node> extends MathFunction<Node> {
-
-    protected final DoubleTransformer<Node> doubleTransformer = new DoubleTransformer<Node>();
-    protected final URI doubleType = URI.create(Constants.NS_XSD + "double");
-
-
-    @Override
-    public Collection<Node> apply(RDFBackend<Node> backend, Node context, Collection<Node>... args)
-            throws IllegalArgumentException {
-
-        ArrayList<Node> result = new ArrayList<Node>();
-        for (Collection<Node> arg : args) {
-            Node res = calc(backend, arg);
-            if (res != null) {
-                result.add(res);
-            }
-        }
-        return result;
-    }
-
-    protected Node calc(RDFBackend<Node> backend, Collection<Node> arg) {
-        /* MIN */
-        double d = Double.MAX_VALUE;
-        Node min = null;
-        for (Node n : arg) {
-            try {
-                Double val = doubleTransformer.transform(backend, n);
-                if (val < d) {
-                    d = val;
-                    min = n;
-                }
-            } catch (IllegalArgumentException e) {
-                // we just ignore non-numeric nodes
-            }
-        }
-
-        return min;
-    }
-
-    @Override
-    public String getDescription() {
-        return "select the min of each argument";
-    }
-
-    @Override
-    public String getSignature() {
-        return "fn:min(LiteralList l [, ...]) :: NumberLiteral(s)";
-    }
-
-    @Override
-    public String getLocalName() {
-        return "min";
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5b8766b3/libraries/ldpath/ldpath-functions-math/src/main/java/at/newmedialab/ldpath/model/functions/math/RoundFunction.java
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-math/src/main/java/at/newmedialab/ldpath/model/functions/math/RoundFunction.java b/libraries/ldpath/ldpath-functions-math/src/main/java/at/newmedialab/ldpath/model/functions/math/RoundFunction.java
deleted file mode 100644
index 14d3b0a..0000000
--- a/libraries/ldpath/ldpath-functions-math/src/main/java/at/newmedialab/ldpath/model/functions/math/RoundFunction.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * Copyright (C) 2013 Salzburg Research.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package at.newmedialab.ldpath.model.functions.math;
-
-import at.newmedialab.ldpath.api.backend.RDFBackend;
-import at.newmedialab.ldpath.model.Constants;
-import at.newmedialab.ldpath.model.transformers.DoubleTransformer;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Collection;
-
-public class RoundFunction<Node> extends MathFunction<Node> {
-
-    protected final DoubleTransformer<Node> doubleTransformer = new DoubleTransformer<Node>();
-    protected final URI intType = URI.create(Constants.NS_XSD + "integer");
-
-    @Override
-    public Collection<Node> apply(RDFBackend<Node> backend, Node context,
-            Collection<Node>... args) throws IllegalArgumentException {
-        if (args.length != 1) {
-            throw new IllegalArgumentException("round takes only one argument");
-        }
-
-        ArrayList<Node> result = new ArrayList<Node>();
-        for (Node node : args[0]) {
-            Node res = calc(backend, node);
-            if (res != null) {
-                result.add(res);
-            }
-        }
-        return result;
-    }
-
-    protected Node calc(RDFBackend<Node> backend, Node node) {
-        /* SUM */
-        try {
-            Double val = doubleTransformer.transform(backend, node);
-            return backend.createLiteral(String.valueOf(Math.round(val)), null,
-                    intType);
-        } catch (IllegalArgumentException e) {
-            return null;
-        }
-
-    }
-
-    @Override
-    public String getDescription() {
-        return "Round each argument to the closest int/long value";
-    }
-
-    @Override
-    public String getSignature() {
-        return "fn:round(LiteralList l) :: IntegerLiteralList";
-    }
-
-    @Override
-    public String getLocalName() {
-        return "round";
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5b8766b3/libraries/ldpath/ldpath-functions-math/src/main/java/at/newmedialab/ldpath/model/functions/math/SumFunction.java
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-math/src/main/java/at/newmedialab/ldpath/model/functions/math/SumFunction.java b/libraries/ldpath/ldpath-functions-math/src/main/java/at/newmedialab/ldpath/model/functions/math/SumFunction.java
deleted file mode 100644
index 49b744d..0000000
--- a/libraries/ldpath/ldpath-functions-math/src/main/java/at/newmedialab/ldpath/model/functions/math/SumFunction.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * Copyright (C) 2013 Salzburg Research.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package at.newmedialab.ldpath.model.functions.math;
-
-import at.newmedialab.ldpath.api.backend.RDFBackend;
-import at.newmedialab.ldpath.model.Constants;
-import at.newmedialab.ldpath.model.transformers.DoubleTransformer;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Collection;
-
-public class SumFunction<Node> extends MathFunction<Node> {
-
-    protected final DoubleTransformer<Node> doubleTransformer = new DoubleTransformer<Node>();
-    protected final URI doubleType = URI.create(Constants.NS_XSD + "double");
-
-    @Override
-    public Collection<Node> apply(RDFBackend<Node> backend, Node context,
-            Collection<Node>... args) throws IllegalArgumentException {
-
-        ArrayList<Node> result = new ArrayList<Node>();
-        for (Collection<Node> arg : args) {
-            Node res = calc(backend, arg);
-            if (res != null) {
-                result.add(res);
-            }
-        }
-        return result;
-    }
-
-    protected Node calc(RDFBackend<Node> backend, Collection<Node> arg) {
-        /* SUM */
-        Double d = 0d;
-        for (Node n : arg) {
-            try {
-                Double val = doubleTransformer.transform(backend, n);
-                d += val.doubleValue();
-            } catch (IllegalArgumentException e) {
-                // we just ignore non-numeric nodes
-            }
-        }
-
-        return backend.createLiteral(String.valueOf(d), null, doubleType);
-    }
-
-    @Override
-    public String getSignature() {
-        return "fn:sum(LiteralList l [, ...]) :: NumberLiteral(s)";
-    }
-
-    @Override
-    public String getDescription() {
-        return "Sum up each argument";
-    }
-
-    @Override
-    public String getLocalName() {
-        return "sum";
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5b8766b3/libraries/ldpath/ldpath-functions-math/src/main/java/org/apache/marmotta/ldpath/model/functions/math/MathFunction.java
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-math/src/main/java/org/apache/marmotta/ldpath/model/functions/math/MathFunction.java b/libraries/ldpath/ldpath-functions-math/src/main/java/org/apache/marmotta/ldpath/model/functions/math/MathFunction.java
new file mode 100644
index 0000000..ea6cb1f
--- /dev/null
+++ b/libraries/ldpath/ldpath-functions-math/src/main/java/org/apache/marmotta/ldpath/model/functions/math/MathFunction.java
@@ -0,0 +1,23 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.ldpath.model.functions.math;
+
+
+import org.apache.marmotta.ldpath.api.functions.SelectorFunction;
+
+public abstract class MathFunction<Node> extends SelectorFunction<Node> {
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5b8766b3/libraries/ldpath/ldpath-functions-math/src/main/java/org/apache/marmotta/ldpath/model/functions/math/MaxFunction.java
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-math/src/main/java/org/apache/marmotta/ldpath/model/functions/math/MaxFunction.java b/libraries/ldpath/ldpath-functions-math/src/main/java/org/apache/marmotta/ldpath/model/functions/math/MaxFunction.java
new file mode 100644
index 0000000..6f423a0
--- /dev/null
+++ b/libraries/ldpath/ldpath-functions-math/src/main/java/org/apache/marmotta/ldpath/model/functions/math/MaxFunction.java
@@ -0,0 +1,80 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.ldpath.model.functions.math;
+
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.marmotta.ldpath.api.backend.RDFBackend;
+import org.apache.marmotta.ldpath.model.Constants;
+import org.apache.marmotta.ldpath.model.transformers.DoubleTransformer;
+
+public class MaxFunction<Node> extends MathFunction<Node> {
+
+    protected final DoubleTransformer<Node> doubleTransformer = new DoubleTransformer<Node>();
+    protected final URI doubleType = URI.create(Constants.NS_XSD + "double");
+
+    @Override
+    public Collection<Node> apply(RDFBackend<Node> backend, Node context,
+            Collection<Node>... args) throws IllegalArgumentException {
+
+        ArrayList<Node> result = new ArrayList<Node>();
+        for (Collection<Node> arg : args) {
+            Node res = calc(backend, arg);
+            if (res != null) {
+                result.add(res);
+            }
+        }
+        return result;
+    }
+
+    protected Node calc(RDFBackend<Node> backend, Collection<Node> arg) {
+        /* MAX */
+        double d = Double.MIN_VALUE;
+        Node max = null;
+        for (Node n : arg) {
+            try {
+                Double val = doubleTransformer.transform(backend, n);
+                if (val > d) {
+                    d = val;
+                    max = n;
+                }
+            } catch (IllegalArgumentException e) {
+                // we just ignore non-numeric nodes
+            }
+        }
+
+        return max;
+    }
+
+    @Override
+    public String getDescription() {
+        return "select the max of each argument";
+    }
+
+    @Override
+    public String getSignature() {
+        return "fn:max(LiteralList l [, ...]) :: NumberLiteral(s)";
+    }
+
+    @Override
+    public String getLocalName() {
+        return "max";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5b8766b3/libraries/ldpath/ldpath-functions-math/src/main/java/org/apache/marmotta/ldpath/model/functions/math/MinFunction.java
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-math/src/main/java/org/apache/marmotta/ldpath/model/functions/math/MinFunction.java b/libraries/ldpath/ldpath-functions-math/src/main/java/org/apache/marmotta/ldpath/model/functions/math/MinFunction.java
new file mode 100644
index 0000000..2116126
--- /dev/null
+++ b/libraries/ldpath/ldpath-functions-math/src/main/java/org/apache/marmotta/ldpath/model/functions/math/MinFunction.java
@@ -0,0 +1,81 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.ldpath.model.functions.math;
+
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.marmotta.ldpath.api.backend.RDFBackend;
+import org.apache.marmotta.ldpath.model.Constants;
+import org.apache.marmotta.ldpath.model.transformers.DoubleTransformer;
+
+public class MinFunction<Node> extends MathFunction<Node> {
+
+    protected final DoubleTransformer<Node> doubleTransformer = new DoubleTransformer<Node>();
+    protected final URI doubleType = URI.create(Constants.NS_XSD + "double");
+
+
+    @Override
+    public Collection<Node> apply(RDFBackend<Node> backend, Node context, Collection<Node>... args)
+            throws IllegalArgumentException {
+
+        ArrayList<Node> result = new ArrayList<Node>();
+        for (Collection<Node> arg : args) {
+            Node res = calc(backend, arg);
+            if (res != null) {
+                result.add(res);
+            }
+        }
+        return result;
+    }
+
+    protected Node calc(RDFBackend<Node> backend, Collection<Node> arg) {
+        /* MIN */
+        double d = Double.MAX_VALUE;
+        Node min = null;
+        for (Node n : arg) {
+            try {
+                Double val = doubleTransformer.transform(backend, n);
+                if (val < d) {
+                    d = val;
+                    min = n;
+                }
+            } catch (IllegalArgumentException e) {
+                // we just ignore non-numeric nodes
+            }
+        }
+
+        return min;
+    }
+
+    @Override
+    public String getDescription() {
+        return "select the min of each argument";
+    }
+
+    @Override
+    public String getSignature() {
+        return "fn:min(LiteralList l [, ...]) :: NumberLiteral(s)";
+    }
+
+    @Override
+    public String getLocalName() {
+        return "min";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5b8766b3/libraries/ldpath/ldpath-functions-math/src/main/java/org/apache/marmotta/ldpath/model/functions/math/RoundFunction.java
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-math/src/main/java/org/apache/marmotta/ldpath/model/functions/math/RoundFunction.java b/libraries/ldpath/ldpath-functions-math/src/main/java/org/apache/marmotta/ldpath/model/functions/math/RoundFunction.java
new file mode 100644
index 0000000..2df5e20
--- /dev/null
+++ b/libraries/ldpath/ldpath-functions-math/src/main/java/org/apache/marmotta/ldpath/model/functions/math/RoundFunction.java
@@ -0,0 +1,76 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.ldpath.model.functions.math;
+
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.marmotta.ldpath.api.backend.RDFBackend;
+import org.apache.marmotta.ldpath.model.Constants;
+import org.apache.marmotta.ldpath.model.transformers.DoubleTransformer;
+
+public class RoundFunction<Node> extends MathFunction<Node> {
+
+    protected final DoubleTransformer<Node> doubleTransformer = new DoubleTransformer<Node>();
+    protected final URI intType = URI.create(Constants.NS_XSD + "integer");
+
+    @Override
+    public Collection<Node> apply(RDFBackend<Node> backend, Node context,
+            Collection<Node>... args) throws IllegalArgumentException {
+        if (args.length != 1) {
+            throw new IllegalArgumentException("round takes only one argument");
+        }
+
+        ArrayList<Node> result = new ArrayList<Node>();
+        for (Node node : args[0]) {
+            Node res = calc(backend, node);
+            if (res != null) {
+                result.add(res);
+            }
+        }
+        return result;
+    }
+
+    protected Node calc(RDFBackend<Node> backend, Node node) {
+        /* SUM */
+        try {
+            Double val = doubleTransformer.transform(backend, node);
+            return backend.createLiteral(String.valueOf(Math.round(val)), null,
+                    intType);
+        } catch (IllegalArgumentException e) {
+            return null;
+        }
+
+    }
+
+    @Override
+    public String getDescription() {
+        return "Round each argument to the closest int/long value";
+    }
+
+    @Override
+    public String getSignature() {
+        return "fn:round(LiteralList l) :: IntegerLiteralList";
+    }
+
+    @Override
+    public String getLocalName() {
+        return "round";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5b8766b3/libraries/ldpath/ldpath-functions-math/src/main/java/org/apache/marmotta/ldpath/model/functions/math/SumFunction.java
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-math/src/main/java/org/apache/marmotta/ldpath/model/functions/math/SumFunction.java b/libraries/ldpath/ldpath-functions-math/src/main/java/org/apache/marmotta/ldpath/model/functions/math/SumFunction.java
new file mode 100644
index 0000000..87d076c
--- /dev/null
+++ b/libraries/ldpath/ldpath-functions-math/src/main/java/org/apache/marmotta/ldpath/model/functions/math/SumFunction.java
@@ -0,0 +1,76 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.ldpath.model.functions.math;
+
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.marmotta.ldpath.api.backend.RDFBackend;
+import org.apache.marmotta.ldpath.model.Constants;
+import org.apache.marmotta.ldpath.model.transformers.DoubleTransformer;
+
+public class SumFunction<Node> extends MathFunction<Node> {
+
+    protected final DoubleTransformer<Node> doubleTransformer = new DoubleTransformer<Node>();
+    protected final URI doubleType = URI.create(Constants.NS_XSD + "double");
+
+    @Override
+    public Collection<Node> apply(RDFBackend<Node> backend, Node context,
+            Collection<Node>... args) throws IllegalArgumentException {
+
+        ArrayList<Node> result = new ArrayList<Node>();
+        for (Collection<Node> arg : args) {
+            Node res = calc(backend, arg);
+            if (res != null) {
+                result.add(res);
+            }
+        }
+        return result;
+    }
+
+    protected Node calc(RDFBackend<Node> backend, Collection<Node> arg) {
+        /* SUM */
+        Double d = 0d;
+        for (Node n : arg) {
+            try {
+                Double val = doubleTransformer.transform(backend, n);
+                d += val.doubleValue();
+            } catch (IllegalArgumentException e) {
+                // we just ignore non-numeric nodes
+            }
+        }
+
+        return backend.createLiteral(String.valueOf(d), null, doubleType);
+    }
+
+    @Override
+    public String getSignature() {
+        return "fn:sum(LiteralList l [, ...]) :: NumberLiteral(s)";
+    }
+
+    @Override
+    public String getDescription() {
+        return "Sum up each argument";
+    }
+
+    @Override
+    public String getLocalName() {
+        return "sum";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5b8766b3/libraries/ldpath/ldpath-functions-math/src/main/resources/META-INF/services/at.newmedialab.ldpath.api.functions.SelectorFunction
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-math/src/main/resources/META-INF/services/at.newmedialab.ldpath.api.functions.SelectorFunction b/libraries/ldpath/ldpath-functions-math/src/main/resources/META-INF/services/at.newmedialab.ldpath.api.functions.SelectorFunction
deleted file mode 100644
index ad01e3b..0000000
--- a/libraries/ldpath/ldpath-functions-math/src/main/resources/META-INF/services/at.newmedialab.ldpath.api.functions.SelectorFunction
+++ /dev/null
@@ -1,4 +0,0 @@
-#at.newmedialab.ldpath.model.functions.math.SumFunction
-at.newmedialab.ldpath.model.functions.math.MinFunction
-at.newmedialab.ldpath.model.functions.math.MaxFunction
-at.newmedialab.ldpath.model.functions.math.RoundFunction
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5b8766b3/libraries/ldpath/ldpath-functions-math/src/main/resources/META-INF/services/org.apache.marmotta.ldpath.api.functions.SelectorFunction
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-math/src/main/resources/META-INF/services/org.apache.marmotta.ldpath.api.functions.SelectorFunction b/libraries/ldpath/ldpath-functions-math/src/main/resources/META-INF/services/org.apache.marmotta.ldpath.api.functions.SelectorFunction
new file mode 100644
index 0000000..4e0b3b0
--- /dev/null
+++ b/libraries/ldpath/ldpath-functions-math/src/main/resources/META-INF/services/org.apache.marmotta.ldpath.api.functions.SelectorFunction
@@ -0,0 +1,4 @@
+#org.apache.marmotta.ldpath.model.functions.math.SumFunction
+org.apache.marmotta.ldpath.model.functions.math.MinFunction
+org.apache.marmotta.ldpath.model.functions.math.MaxFunction
+org.apache.marmotta.ldpath.model.functions.math.RoundFunction
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5b8766b3/libraries/ldpath/ldpath-functions-math/src/test/java/math/MathFunctionTest.java
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-math/src/test/java/math/MathFunctionTest.java b/libraries/ldpath/ldpath-functions-math/src/test/java/math/MathFunctionTest.java
deleted file mode 100644
index eb32173..0000000
--- a/libraries/ldpath/ldpath-functions-math/src/test/java/math/MathFunctionTest.java
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Copyright (c) 2013 Salzburg Research.
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package math;
-
-import at.newmedialab.ldpath.model.fields.FieldMapping;
-import at.newmedialab.ldpath.parser.ParseException;
-import at.newmedialab.ldpath.parser.RdfPathParser;
-import core.AbstractTestBase;
-import org.hamcrest.CoreMatchers;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.openrdf.model.URI;
-import org.openrdf.model.Value;
-import org.openrdf.model.ValueFactory;
-import org.openrdf.repository.RepositoryException;
-import org.openrdf.repository.sail.SailRepositoryConnection;
-
-import java.util.Collection;
-import java.util.Random;
-
-
-public class MathFunctionTest extends AbstractTestBase {
-
-    private int[] iData;
-    private long[] lData;
-    private float[] fData;
-    private double[] dData;
-    private URI subject;
-    private URI iProp, lProp, fProp, dProp;
-
-    @Before
-    public void createData() throws RepositoryException {
-        final Random rnd = new Random();
-        final int tSize = 30;
-
-        // We test int, long, float and double
-        iData = new int[tSize];
-        lData = new long[tSize];
-        fData = new float[tSize];
-        dData = new double[tSize];
-
-        for (int i = 0; i < tSize; i++) {
-            iData[i] = rnd.nextInt(tSize);
-            lData[i] = rnd.nextInt();
-            fData[i] = rnd.nextInt(1000000) * 10e-4f;
-            dData[i] = rnd.nextInt() * 10e-8f;
-        }
-
-        subject = repository.getValueFactory().createURI(NSS.get("ex") + rnd.nextInt());
-        iProp = repository.getValueFactory().createURI(NSS.get("foo") + "integer");
-        lProp = repository.getValueFactory().createURI(NSS.get("foo") + "long");
-        fProp = repository.getValueFactory().createURI(NSS.get("foo") + "float");
-        dProp = repository.getValueFactory().createURI(NSS.get("foo") + "double");
-
-        final SailRepositoryConnection con = repository.getConnection();
-        try {
-            final ValueFactory vF = con.getValueFactory();
-
-            for (int i = 0; i < tSize; i++) {
-                con.add(vF.createStatement(subject, iProp, vF.createLiteral(iData[i])));
-                con.add(vF.createStatement(subject, lProp, vF.createLiteral(lData[i])));
-                con.add(vF.createStatement(subject, fProp, vF.createLiteral(fData[i])));
-                con.add(vF.createStatement(subject, dProp, vF.createLiteral(dData[i])));
-            }
-
-            con.commit();
-        } finally {
-            con.close();
-        }
-    }
-
-    @Test
-    public void testMin() throws ParseException {
-        int iMin = Integer.MAX_VALUE;
-        long lMin = Long.MAX_VALUE;
-        float fMin = Float.MAX_VALUE;
-        double dMin = Double.MAX_VALUE;
-        for (int i = 0; i < iData.length; i++) {
-            iMin = Math.min(iMin, iData[i]);
-            lMin = Math.min(lMin, lData[i]);
-            fMin = Math.min(fMin, fData[i]);
-            dMin = Math.min(dMin, dData[i]);
-        }
-
-        final RdfPathParser<Value> intParser = createParserFromString("fn:min(<" + iProp.stringValue() + ">) :: xsd:int");
-        final FieldMapping<Object, Value> intRule = intParser.parseRule(NSS);
-        final Collection<Object> intResult = intRule.getValues(backend, subject);
-
-        Assert.assertEquals("Integer", 1, intResult.size());
-        final Object intNext = intResult.iterator().next();
-        Assert.assertTrue("Integer (type)", intNext instanceof Integer);
-        Assert.assertEquals("Integer (result)", iMin, intNext);
-
-        final RdfPathParser<Value> longParser = createParserFromString("fn:min(<" + lProp.stringValue() + ">) :: xsd:long");
-        final FieldMapping<Object, Value> longRule = longParser.parseRule(NSS);
-        final Collection<Object> longResult = longRule.getValues(backend, subject);
-
-        Assert.assertEquals("Long", 1, longResult.size());
-        final Object longNext = longResult.iterator().next();
-        Assert.assertTrue("Long (type)", longNext instanceof Long);
-        Assert.assertEquals("Long (result)", lMin, longNext);
-
-        final RdfPathParser<Value> floatParser = createParserFromString("fn:min(<" + fProp.stringValue() + ">) :: xsd:float");
-        final FieldMapping<Object, Value> floatRule = floatParser.parseRule(NSS);
-        final Collection<Object> floatResult = floatRule.getValues(backend, subject);
-
-        Assert.assertEquals("Float", 1, floatResult.size());
-        final Object floatNext = floatResult.iterator().next();
-        Assert.assertTrue("Float (type)", floatNext instanceof Float);
-        Assert.assertEquals("Float (result)", fMin, floatNext);
-
-        final RdfPathParser<Value> doubleParser = createParserFromString("fn:min(<" + dProp.stringValue() + ">) :: xsd:double");
-        final FieldMapping<Object, Value> doubleRule = doubleParser.parseRule(NSS);
-        final Collection<Object> doubleResult = doubleRule.getValues(backend, subject);
-
-        Assert.assertEquals("Double", 1, doubleResult.size());
-        final Object doubleNext = doubleResult.iterator().next();
-        Assert.assertTrue("Double (type)", doubleNext instanceof Double);
-        Assert.assertEquals("Double (result)", dMin, doubleNext);
-    }
-
-    @Test
-    public void testMax() throws ParseException {
-        int iMax = Integer.MIN_VALUE;
-        long lMax = Long.MIN_VALUE;
-        float fMax = Float.MIN_VALUE;
-        double dMax = Double.MIN_VALUE;
-        for (int i = 0; i < iData.length; i++) {
-            iMax = Math.max(iMax, iData[i]);
-            lMax = Math.max(lMax, lData[i]);
-            fMax = Math.max(fMax, fData[i]);
-            dMax = Math.max(dMax, dData[i]);
-        }
-
-        final RdfPathParser<Value> intParser = createParserFromString("fn:max(<" + iProp.stringValue() + ">) :: xsd:int");
-        final FieldMapping<Object, Value> intRule = intParser.parseRule(NSS);
-        final Collection<Object> intResult = intRule.getValues(backend, subject);
-
-        Assert.assertEquals("Integer", 1, intResult.size());
-        final Object intNext = intResult.iterator().next();
-        Assert.assertTrue("Integer (type)", intNext instanceof Integer);
-        Assert.assertEquals("Integer (result)", iMax, intNext);
-
-        final RdfPathParser<Value> longParser = createParserFromString("fn:max(<" + lProp.stringValue() + ">) :: xsd:long");
-        final FieldMapping<Object, Value> longRule = longParser.parseRule(NSS);
-        final Collection<Object> longResult = longRule.getValues(backend, subject);
-
-        Assert.assertEquals("Long", 1, longResult.size());
-        final Object longNext = longResult.iterator().next();
-        Assert.assertTrue("Long (type)", longNext instanceof Long);
-        Assert.assertEquals("Long (result)", lMax, longNext);
-
-        final RdfPathParser<Value> floatParser = createParserFromString("fn:max(<" + fProp.stringValue() + ">) :: xsd:float");
-        final FieldMapping<Object, Value> floatRule = floatParser.parseRule(NSS);
-        final Collection<Object> floatResult = floatRule.getValues(backend, subject);
-
-        Assert.assertEquals("Float", 1, floatResult.size());
-        final Object floatNext = floatResult.iterator().next();
-        Assert.assertTrue("Float (type)", floatNext instanceof Float);
-        Assert.assertEquals("Float (result)", fMax, floatNext);
-
-        final RdfPathParser<Value> doubleParser = createParserFromString("fn:max(<" + dProp.stringValue() + ">) :: xsd:double");
-        final FieldMapping<Object, Value> doubleRule = doubleParser.parseRule(NSS);
-        final Collection<Object> doubleResult = doubleRule.getValues(backend, subject);
-
-        Assert.assertEquals("Double", 1, doubleResult.size());
-        final Object doubleNext = doubleResult.iterator().next();
-        Assert.assertTrue("Double (type)", doubleNext instanceof Double);
-        Assert.assertEquals("Double (result)", dMax, doubleNext);
-    }
-
-    @Test
-    public void testRound() throws ParseException {
-        float fMin = Float.MAX_VALUE;
-        double dMin = Double.MAX_VALUE;
-        for (int i = 0; i < fData.length; i++) {
-            fMin = Math.min(fMin, fData[i]);
-            dMin = Math.min(dMin, dData[i]);
-        }
-
-        final RdfPathParser<Value> floatParser = createParserFromString("fn:round(<" + fProp.stringValue() + ">) :: xsd:int");
-        final FieldMapping<Object, Value> floatRule = floatParser.parseRule(NSS);
-        final Collection<Object> floatResult = floatRule.getValues(backend, subject);
-
-        Assert.assertEquals("round[Float]", fData.length, floatResult.size());
-        for (float element : fData) {
-            Assert.assertThat("round[Float] (result)", floatResult, CoreMatchers.hasItem(Math.round(element)));
-        }
-
-        final RdfPathParser<Value> doubleParser = createParserFromString("fn:round(<" + dProp.stringValue() + ">) :: xsd:long");
-        final FieldMapping<Object, Value> doubleRule = doubleParser.parseRule(NSS);
-        final Collection<Object> doubleResult = doubleRule.getValues(backend, subject);
-
-        Assert.assertEquals("round[Double]", dData.length, doubleResult.size());
-        for (double element : dData) {
-            Assert.assertThat("round[Double] (result)", doubleResult, CoreMatchers.hasItem(Math.round(element)));
-        }
-
-    }
-
-    @Test
-    @Ignore("fn:sum has serious design issues")
-    public void testSum() throws ParseException {
-        int iSum = 0;
-        long lSum = 0l;
-        float fSum = 0f;
-        double dSum = 0d;
-        for (int i = 0; i < iData.length; i++) {
-            iSum += iData[i];
-            lSum += lData[i];
-            fSum += fData[i];
-            dSum += dData[i];
-        }
-
-        final RdfPathParser<Value> intParser = createParserFromString("fn:sum(<" + iProp.stringValue() + ">) :: xsd:int");
-        final FieldMapping<Object, Value> intRule = intParser.parseRule(NSS);
-        final Collection<Object> intResult = intRule.getValues(backend, subject);
-
-        Assert.assertEquals("Integer", 1, intResult.size());
-        final Object intNext = intResult.iterator().next();
-        Assert.assertTrue("Integer (type)", intNext instanceof Integer);
-        Assert.assertEquals("Integer (result)", iSum, intNext);
-
-        final RdfPathParser<Value> longParser = createParserFromString("fn:sum(<" + lProp.stringValue() + ">) :: xsd:long");
-        final FieldMapping<Object, Value> longRule = longParser.parseRule(NSS);
-        final Collection<Object> longResult = longRule.getValues(backend, subject);
-
-        Assert.assertEquals("Long", 1, longResult.size());
-        final Object longNext = longResult.iterator().next();
-        Assert.assertTrue("Long (type)", longNext instanceof Long);
-        Assert.assertEquals("Long (result)", lSum, longNext);
-
-        final RdfPathParser<Value> floatParser = createParserFromString("fn:sum(<" + fProp.stringValue() + ">) :: xsd:float");
-        final FieldMapping<Object, Value> floatRule = floatParser.parseRule(NSS);
-        final Collection<Object> floatResult = floatRule.getValues(backend, subject);
-
-        Assert.assertEquals("Float", 1, floatResult.size());
-        final Object floatNext = floatResult.iterator().next();
-        Assert.assertTrue("Float (type)", floatNext instanceof Float);
-        Assert.assertEquals("Float (result)", fSum, floatNext);
-
-        final RdfPathParser<Value> doubleParser = createParserFromString("fn:sum(<" + dProp.stringValue() + ">) :: xsd:double");
-        final FieldMapping<Object, Value> doubleRule = doubleParser.parseRule(NSS);
-        final Collection<Object> doubleResult = doubleRule.getValues(backend, subject);
-
-        Assert.assertEquals("Double", 1, doubleResult.size());
-        final Object doubleNext = doubleResult.iterator().next();
-        Assert.assertTrue("Double (type)", doubleNext instanceof Double);
-        Assert.assertEquals("Double (result)", dSum, doubleNext);
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5b8766b3/libraries/ldpath/ldpath-functions-math/src/test/java/org/apache/marmotta/ldpath/model/functions/math/MathFunctionTest.java
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-math/src/test/java/org/apache/marmotta/ldpath/model/functions/math/MathFunctionTest.java b/libraries/ldpath/ldpath-functions-math/src/test/java/org/apache/marmotta/ldpath/model/functions/math/MathFunctionTest.java
new file mode 100644
index 0000000..e7c5078
--- /dev/null
+++ b/libraries/ldpath/ldpath-functions-math/src/test/java/org/apache/marmotta/ldpath/model/functions/math/MathFunctionTest.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright (c) 2013 Salzburg Research.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.marmotta.ldpath.model.functions.math;
+
+import java.util.Collection;
+import java.util.Random;
+
+import org.apache.marmotta.ldpath.model.fields.FieldMapping;
+import org.apache.marmotta.ldpath.parser.ParseException;
+import org.apache.marmotta.ldpath.parser.RdfPathParser;
+import org.apache.marmotta.ldpath.test.AbstractTestBase;
+import org.hamcrest.CoreMatchers;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.openrdf.model.URI;
+import org.openrdf.model.Value;
+import org.openrdf.model.ValueFactory;
+import org.openrdf.repository.RepositoryException;
+import org.openrdf.repository.sail.SailRepositoryConnection;
+
+
+
+public class MathFunctionTest extends AbstractTestBase {
+
+    private int[] iData;
+    private long[] lData;
+    private float[] fData;
+    private double[] dData;
+    private URI subject;
+    private URI iProp, lProp, fProp, dProp;
+
+    @Before
+    public void createData() throws RepositoryException {
+        final Random rnd = new Random();
+        final int tSize = 30;
+
+        // We test int, long, float and double
+        iData = new int[tSize];
+        lData = new long[tSize];
+        fData = new float[tSize];
+        dData = new double[tSize];
+
+        for (int i = 0; i < tSize; i++) {
+            iData[i] = rnd.nextInt(tSize);
+            lData[i] = rnd.nextInt();
+            fData[i] = rnd.nextInt(1000000) * 10e-4f;
+            dData[i] = rnd.nextInt() * 10e-8f;
+        }
+
+        subject = repository.getValueFactory().createURI(NSS.get("ex") + rnd.nextInt());
+        iProp = repository.getValueFactory().createURI(NSS.get("foo") + "integer");
+        lProp = repository.getValueFactory().createURI(NSS.get("foo") + "long");
+        fProp = repository.getValueFactory().createURI(NSS.get("foo") + "float");
+        dProp = repository.getValueFactory().createURI(NSS.get("foo") + "double");
+
+        final SailRepositoryConnection con = repository.getConnection();
+        try {
+            final ValueFactory vF = con.getValueFactory();
+
+            for (int i = 0; i < tSize; i++) {
+                con.add(vF.createStatement(subject, iProp, vF.createLiteral(iData[i])));
+                con.add(vF.createStatement(subject, lProp, vF.createLiteral(lData[i])));
+                con.add(vF.createStatement(subject, fProp, vF.createLiteral(fData[i])));
+                con.add(vF.createStatement(subject, dProp, vF.createLiteral(dData[i])));
+            }
+
+            con.commit();
+        } finally {
+            con.close();
+        }
+    }
+
+    @Test
+    public void testMin() throws ParseException {
+        int iMin = Integer.MAX_VALUE;
+        long lMin = Long.MAX_VALUE;
+        float fMin = Float.MAX_VALUE;
+        double dMin = Double.MAX_VALUE;
+        for (int i = 0; i < iData.length; i++) {
+            iMin = Math.min(iMin, iData[i]);
+            lMin = Math.min(lMin, lData[i]);
+            fMin = Math.min(fMin, fData[i]);
+            dMin = Math.min(dMin, dData[i]);
+        }
+
+        final RdfPathParser<Value> intParser = createParserFromString("fn:min(<" + iProp.stringValue() + ">) :: xsd:int");
+        final FieldMapping<Object, Value> intRule = intParser.parseRule(NSS);
+        final Collection<Object> intResult = intRule.getValues(backend, subject);
+
+        Assert.assertEquals("Integer", 1, intResult.size());
+        final Object intNext = intResult.iterator().next();
+        Assert.assertTrue("Integer (type)", intNext instanceof Integer);
+        Assert.assertEquals("Integer (result)", iMin, intNext);
+
+        final RdfPathParser<Value> longParser = createParserFromString("fn:min(<" + lProp.stringValue() + ">) :: xsd:long");
+        final FieldMapping<Object, Value> longRule = longParser.parseRule(NSS);
+        final Collection<Object> longResult = longRule.getValues(backend, subject);
+
+        Assert.assertEquals("Long", 1, longResult.size());
+        final Object longNext = longResult.iterator().next();
+        Assert.assertTrue("Long (type)", longNext instanceof Long);
+        Assert.assertEquals("Long (result)", lMin, longNext);
+
+        final RdfPathParser<Value> floatParser = createParserFromString("fn:min(<" + fProp.stringValue() + ">) :: xsd:float");
+        final FieldMapping<Object, Value> floatRule = floatParser.parseRule(NSS);
+        final Collection<Object> floatResult = floatRule.getValues(backend, subject);
+
+        Assert.assertEquals("Float", 1, floatResult.size());
+        final Object floatNext = floatResult.iterator().next();
+        Assert.assertTrue("Float (type)", floatNext instanceof Float);
+        Assert.assertEquals("Float (result)", fMin, floatNext);
+
+        final RdfPathParser<Value> doubleParser = createParserFromString("fn:min(<" + dProp.stringValue() + ">) :: xsd:double");
+        final FieldMapping<Object, Value> doubleRule = doubleParser.parseRule(NSS);
+        final Collection<Object> doubleResult = doubleRule.getValues(backend, subject);
+
+        Assert.assertEquals("Double", 1, doubleResult.size());
+        final Object doubleNext = doubleResult.iterator().next();
+        Assert.assertTrue("Double (type)", doubleNext instanceof Double);
+        Assert.assertEquals("Double (result)", dMin, doubleNext);
+    }
+
+    @Test
+    public void testMax() throws ParseException {
+        int iMax = Integer.MIN_VALUE;
+        long lMax = Long.MIN_VALUE;
+        float fMax = Float.MIN_VALUE;
+        double dMax = Double.MIN_VALUE;
+        for (int i = 0; i < iData.length; i++) {
+            iMax = Math.max(iMax, iData[i]);
+            lMax = Math.max(lMax, lData[i]);
+            fMax = Math.max(fMax, fData[i]);
+            dMax = Math.max(dMax, dData[i]);
+        }
+
+        final RdfPathParser<Value> intParser = createParserFromString("fn:max(<" + iProp.stringValue() + ">) :: xsd:int");
+        final FieldMapping<Object, Value> intRule = intParser.parseRule(NSS);
+        final Collection<Object> intResult = intRule.getValues(backend, subject);
+
+        Assert.assertEquals("Integer", 1, intResult.size());
+        final Object intNext = intResult.iterator().next();
+        Assert.assertTrue("Integer (type)", intNext instanceof Integer);
+        Assert.assertEquals("Integer (result)", iMax, intNext);
+
+        final RdfPathParser<Value> longParser = createParserFromString("fn:max(<" + lProp.stringValue() + ">) :: xsd:long");
+        final FieldMapping<Object, Value> longRule = longParser.parseRule(NSS);
+        final Collection<Object> longResult = longRule.getValues(backend, subject);
+
+        Assert.assertEquals("Long", 1, longResult.size());
+        final Object longNext = longResult.iterator().next();
+        Assert.assertTrue("Long (type)", longNext instanceof Long);
+        Assert.assertEquals("Long (result)", lMax, longNext);
+
+        final RdfPathParser<Value> floatParser = createParserFromString("fn:max(<" + fProp.stringValue() + ">) :: xsd:float");
+        final FieldMapping<Object, Value> floatRule = floatParser.parseRule(NSS);
+        final Collection<Object> floatResult = floatRule.getValues(backend, subject);
+
+        Assert.assertEquals("Float", 1, floatResult.size());
+        final Object floatNext = floatResult.iterator().next();
+        Assert.assertTrue("Float (type)", floatNext instanceof Float);
+        Assert.assertEquals("Float (result)", fMax, floatNext);
+
+        final RdfPathParser<Value> doubleParser = createParserFromString("fn:max(<" + dProp.stringValue() + ">) :: xsd:double");
+        final FieldMapping<Object, Value> doubleRule = doubleParser.parseRule(NSS);
+        final Collection<Object> doubleResult = doubleRule.getValues(backend, subject);
+
+        Assert.assertEquals("Double", 1, doubleResult.size());
+        final Object doubleNext = doubleResult.iterator().next();
+        Assert.assertTrue("Double (type)", doubleNext instanceof Double);
+        Assert.assertEquals("Double (result)", dMax, doubleNext);
+    }
+
+    @Test
+    public void testRound() throws ParseException {
+        float fMin = Float.MAX_VALUE;
+        double dMin = Double.MAX_VALUE;
+        for (int i = 0; i < fData.length; i++) {
+            fMin = Math.min(fMin, fData[i]);
+            dMin = Math.min(dMin, dData[i]);
+        }
+
+        final RdfPathParser<Value> floatParser = createParserFromString("fn:round(<" + fProp.stringValue() + ">) :: xsd:int");
+        final FieldMapping<Object, Value> floatRule = floatParser.parseRule(NSS);
+        final Collection<Object> floatResult = floatRule.getValues(backend, subject);
+
+        Assert.assertEquals("round[Float]", fData.length, floatResult.size());
+        for (float element : fData) {
+            Assert.assertThat("round[Float] (result)", floatResult, CoreMatchers.hasItem(Math.round(element)));
+        }
+
+        final RdfPathParser<Value> doubleParser = createParserFromString("fn:round(<" + dProp.stringValue() + ">) :: xsd:long");
+        final FieldMapping<Object, Value> doubleRule = doubleParser.parseRule(NSS);
+        final Collection<Object> doubleResult = doubleRule.getValues(backend, subject);
+
+        Assert.assertEquals("round[Double]", dData.length, doubleResult.size());
+        for (double element : dData) {
+            Assert.assertThat("round[Double] (result)", doubleResult, CoreMatchers.hasItem(Math.round(element)));
+        }
+
+    }
+
+    @Test
+    @Ignore("fn:sum has serious design issues")
+    public void testSum() throws ParseException {
+        int iSum = 0;
+        long lSum = 0l;
+        float fSum = 0f;
+        double dSum = 0d;
+        for (int i = 0; i < iData.length; i++) {
+            iSum += iData[i];
+            lSum += lData[i];
+            fSum += fData[i];
+            dSum += dData[i];
+        }
+
+        final RdfPathParser<Value> intParser = createParserFromString("fn:sum(<" + iProp.stringValue() + ">) :: xsd:int");
+        final FieldMapping<Object, Value> intRule = intParser.parseRule(NSS);
+        final Collection<Object> intResult = intRule.getValues(backend, subject);
+
+        Assert.assertEquals("Integer", 1, intResult.size());
+        final Object intNext = intResult.iterator().next();
+        Assert.assertTrue("Integer (type)", intNext instanceof Integer);
+        Assert.assertEquals("Integer (result)", iSum, intNext);
+
+        final RdfPathParser<Value> longParser = createParserFromString("fn:sum(<" + lProp.stringValue() + ">) :: xsd:long");
+        final FieldMapping<Object, Value> longRule = longParser.parseRule(NSS);
+        final Collection<Object> longResult = longRule.getValues(backend, subject);
+
+        Assert.assertEquals("Long", 1, longResult.size());
+        final Object longNext = longResult.iterator().next();
+        Assert.assertTrue("Long (type)", longNext instanceof Long);
+        Assert.assertEquals("Long (result)", lSum, longNext);
+
+        final RdfPathParser<Value> floatParser = createParserFromString("fn:sum(<" + fProp.stringValue() + ">) :: xsd:float");
+        final FieldMapping<Object, Value> floatRule = floatParser.parseRule(NSS);
+        final Collection<Object> floatResult = floatRule.getValues(backend, subject);
+
+        Assert.assertEquals("Float", 1, floatResult.size());
+        final Object floatNext = floatResult.iterator().next();
+        Assert.assertTrue("Float (type)", floatNext instanceof Float);
+        Assert.assertEquals("Float (result)", fSum, floatNext);
+
+        final RdfPathParser<Value> doubleParser = createParserFromString("fn:sum(<" + dProp.stringValue() + ">) :: xsd:double");
+        final FieldMapping<Object, Value> doubleRule = doubleParser.parseRule(NSS);
+        final Collection<Object> doubleResult = doubleRule.getValues(backend, subject);
+
+        Assert.assertEquals("Double", 1, doubleResult.size());
+        final Object doubleNext = doubleResult.iterator().next();
+        Assert.assertTrue("Double (type)", doubleNext instanceof Double);
+        Assert.assertEquals("Double (result)", dSum, doubleNext);
+
+    }
+
+}