1   /*
2    * RDFpro - An extensible tool for building stream-oriented RDF processing libraries.
3    * 
4    * Written in 2015 by Francesco Corcoglioniti with support by Alessio Palmero Aprosio and Marco
5    * Rospocher. Contact info on http://rdfpro.fbk.eu/
6    * 
7    * To the extent possible under law, the authors have dedicated all copyright and related and
8    * neighboring rights to this software to the public domain worldwide. This software is
9    * distributed without any warranty.
10   * 
11   * You should have received a copy of the CC0 Public Domain Dedication along with this software.
12   * If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
13   */
14  package eu.fbk.rdfpro.internal;
15  
16  import java.util.ArrayList;
17  import java.util.List;
18  
19  import org.openrdf.model.BNode;
20  import org.openrdf.model.Literal;
21  import org.openrdf.model.URI;
22  import org.openrdf.model.Value;
23  import org.openrdf.model.ValueFactory;
24  import org.openrdf.query.algebra.evaluation.ValueExprEvaluationException;
25  import org.openrdf.query.algebra.evaluation.function.Function;
26  
27  import eu.fbk.rdfpro.util.Hash;
28  import eu.fbk.rdfpro.vocab.RR;
29  
30  public class FunctionMint implements Function {
31  
32      private static final String DEFAULT_NS = "urn:hash:";
33  
34      @Override
35      public String getURI() {
36          return RR.MINT.stringValue();
37      }
38  
39      @Override
40      public Value evaluate(final ValueFactory factory, final Value... args)
41              throws ValueExprEvaluationException {
42  
43          String ns = null;
44          String name = null;
45          final List<String> strings = new ArrayList<>(8);
46  
47          for (final Value arg : args) {
48              if (arg instanceof URI) {
49                  final URI uri = (URI) arg;
50                  final String string = uri.stringValue();
51                  strings.add("\u0001");
52                  strings.add(string);
53                  if (ns == null) {
54                      ns = uri.getNamespace();
55                  }
56                  if (name == null) {
57                      final char ch = string.charAt(string.length() - 1);
58                      if (ch != ':' && ch != '/' && ch != '#') {
59                          name = uri.getLocalName();
60                      }
61                  }
62  
63              } else if (arg instanceof BNode) {
64                  final BNode bnode = (BNode) arg;
65                  strings.add("\u0002");
66                  strings.add(bnode.getID());
67                  if (name == null) {
68                      name = bnode.getID();
69                  }
70  
71              } else {
72                  final Literal l = (Literal) arg;
73                  if (l.getLanguage() != null) {
74                      strings.add("\u0003");
75                      strings.add(l.getLanguage());
76                  } else if (l.getDatatype() != null) {
77                      strings.add("\u0004");
78                      strings.add(l.getDatatype().stringValue());
79                  } else {
80                      strings.add("\u0005");
81                  }
82                  strings.add(l.getLabel());
83                  if (name == null) {
84                      name = l.getLabel();
85                  }
86              }
87          }
88  
89          final Hash hash = Hash.murmur3(strings.toArray(new String[strings.size()]));
90  
91          final StringBuilder builder = new StringBuilder();
92          builder.append(ns != null ? ns : DEFAULT_NS);
93          if (name != null) {
94              builder.append(name.replaceAll("\\s+", "_")).append('_');
95          }
96          builder.append(hash.toString());
97  
98          return factory.createURI(builder.toString());
99      }
100 
101 }