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.HashSet;
18  import java.util.List;
19  import java.util.Set;
20  
21  import org.openrdf.model.URI;
22  import org.openrdf.model.Value;
23  import org.openrdf.model.ValueFactory;
24  import org.openrdf.model.vocabulary.RDF;
25  import org.openrdf.model.vocabulary.RDFS;
26  import org.openrdf.model.vocabulary.XMLSchema;
27  import org.openrdf.query.algebra.evaluation.ValueExprEvaluationException;
28  import org.openrdf.query.algebra.evaluation.function.Function;
29  
30  import eu.fbk.rdfpro.vocab.RR;
31  
32  public class FunctionCompatibleDatatype implements Function {
33  
34      private static final Set<Pair> COMPATIBILITIES;
35  
36      static {
37          final Set<Pair> set = new HashSet<>();
38  
39          set.add(new Pair(RDFS.LITERAL, RDF.XMLLITERAL));
40          set.add(new Pair(RDFS.LITERAL, XMLSchema.DURATION));
41          set.add(new Pair(RDFS.LITERAL, XMLSchema.DATETIME));
42          set.add(new Pair(RDFS.LITERAL, XMLSchema.DATE));
43          set.add(new Pair(RDFS.LITERAL, XMLSchema.TIME));
44          set.add(new Pair(RDFS.LITERAL, XMLSchema.GYEARMONTH));
45          set.add(new Pair(RDFS.LITERAL, XMLSchema.GMONTHDAY));
46          set.add(new Pair(RDFS.LITERAL, XMLSchema.GYEAR));
47          set.add(new Pair(RDFS.LITERAL, XMLSchema.GMONTH));
48          set.add(new Pair(RDFS.LITERAL, XMLSchema.GDAY));
49          set.add(new Pair(RDFS.LITERAL, XMLSchema.BOOLEAN));
50          set.add(new Pair(RDFS.LITERAL, XMLSchema.BASE64BINARY));
51          set.add(new Pair(RDFS.LITERAL, XMLSchema.HEXBINARY));
52          set.add(new Pair(RDFS.LITERAL, XMLSchema.FLOAT));
53          set.add(new Pair(RDFS.LITERAL, XMLSchema.DOUBLE));
54          set.add(new Pair(RDFS.LITERAL, XMLSchema.DECIMAL));
55          set.add(new Pair(RDFS.LITERAL, XMLSchema.ANYURI));
56          set.add(new Pair(RDFS.LITERAL, XMLSchema.QNAME));
57          set.add(new Pair(RDFS.LITERAL, XMLSchema.NOTATION));
58          set.add(new Pair(RDFS.LITERAL, XMLSchema.STRING));
59          set.add(new Pair(XMLSchema.DECIMAL, XMLSchema.INTEGER));
60          set.add(new Pair(XMLSchema.INTEGER, XMLSchema.NON_POSITIVE_INTEGER));
61          set.add(new Pair(XMLSchema.INTEGER, XMLSchema.NON_NEGATIVE_INTEGER));
62          set.add(new Pair(XMLSchema.INTEGER, XMLSchema.LONG));
63          set.add(new Pair(XMLSchema.NON_POSITIVE_INTEGER, XMLSchema.NEGATIVE_INTEGER));
64          set.add(new Pair(XMLSchema.NON_NEGATIVE_INTEGER, XMLSchema.POSITIVE_INTEGER));
65          set.add(new Pair(XMLSchema.NON_NEGATIVE_INTEGER, XMLSchema.UNSIGNED_LONG));
66          set.add(new Pair(XMLSchema.UNSIGNED_LONG, XMLSchema.UNSIGNED_INT));
67          set.add(new Pair(XMLSchema.UNSIGNED_INT, XMLSchema.UNSIGNED_SHORT));
68          set.add(new Pair(XMLSchema.UNSIGNED_SHORT, XMLSchema.UNSIGNED_BYTE));
69          set.add(new Pair(XMLSchema.LONG, XMLSchema.INT));
70          set.add(new Pair(XMLSchema.INT, XMLSchema.SHORT));
71          set.add(new Pair(XMLSchema.SHORT, XMLSchema.BYTE));
72          set.add(new Pair(XMLSchema.STRING, XMLSchema.NORMALIZEDSTRING));
73          set.add(new Pair(XMLSchema.NORMALIZEDSTRING, XMLSchema.TOKEN));
74          set.add(new Pair(XMLSchema.TOKEN, XMLSchema.LANGUAGE));
75          set.add(new Pair(XMLSchema.TOKEN, XMLSchema.NAME));
76          set.add(new Pair(XMLSchema.TOKEN, XMLSchema.NMTOKEN));
77          set.add(new Pair(XMLSchema.NAME, XMLSchema.NCNAME));
78          set.add(new Pair(XMLSchema.NCNAME, XMLSchema.ID));
79          set.add(new Pair(XMLSchema.NCNAME, XMLSchema.IDREF));
80          set.add(new Pair(XMLSchema.NCNAME, XMLSchema.ENTITY));
81  
82          while (true) {
83              final int sizeBefore = set.size();
84              final List<Pair> pairs = new ArrayList<>(set);
85              for (final Pair pair1 : pairs) {
86                  for (final Pair pair2 : pairs) {
87                      if (pair1.child.equals(pair2.parent)) {
88                          set.add(new Pair(pair1.parent, pair2.child));
89                      }
90                  }
91              }
92              if (set.size() == sizeBefore) {
93                  break;
94              }
95          }
96  
97          for (final URI uri : new URI[] { RDFS.LITERAL, RDF.XMLLITERAL, XMLSchema.DURATION,
98                  XMLSchema.DATETIME, XMLSchema.DATE, XMLSchema.TIME, XMLSchema.GYEARMONTH,
99                  XMLSchema.GMONTHDAY, XMLSchema.GYEAR, XMLSchema.GMONTH, XMLSchema.GDAY,
100                 XMLSchema.BOOLEAN, XMLSchema.BASE64BINARY, XMLSchema.HEXBINARY, XMLSchema.FLOAT,
101                 XMLSchema.DOUBLE, XMLSchema.DECIMAL, XMLSchema.ANYURI, XMLSchema.QNAME,
102                 XMLSchema.NOTATION, XMLSchema.STRING, XMLSchema.INTEGER,
103                 XMLSchema.NON_POSITIVE_INTEGER, XMLSchema.NON_NEGATIVE_INTEGER, XMLSchema.LONG,
104                 XMLSchema.NEGATIVE_INTEGER, XMLSchema.POSITIVE_INTEGER, XMLSchema.UNSIGNED_LONG,
105                 XMLSchema.UNSIGNED_INT, XMLSchema.UNSIGNED_SHORT, XMLSchema.UNSIGNED_BYTE,
106                 XMLSchema.INT, XMLSchema.SHORT, XMLSchema.BYTE, XMLSchema.NORMALIZEDSTRING,
107                 XMLSchema.TOKEN, XMLSchema.LANGUAGE, XMLSchema.NAME, XMLSchema.NMTOKEN,
108                 XMLSchema.NCNAME, XMLSchema.ID, XMLSchema.IDREF, XMLSchema.ENTITY, }) {
109             set.add(new Pair(uri, uri));
110         }
111 
112         COMPATIBILITIES = set;
113     }
114 
115     @Override
116     public String getURI() {
117         return RR.COMPATIBLE_DATATYPE.stringValue();
118     }
119 
120     @Override
121     public Value evaluate(final ValueFactory factory, final Value... args)
122             throws ValueExprEvaluationException {
123         final URI d1 = (URI) args[0]; // parent
124         final URI d2 = (URI) args[1]; // child
125         final Pair pair = new Pair(d1, d2);
126         return factory.createLiteral(COMPATIBILITIES.contains(pair));
127     }
128 
129     private static final class Pair {
130 
131         public URI parent;
132 
133         public URI child;
134 
135         public Pair(final URI parent, final URI child) {
136             this.parent = parent;
137             this.child = child;
138         }
139 
140         @Override
141         public boolean equals(final Object object) {
142             if (object == this) {
143                 return true;
144             }
145             if (!(object instanceof Pair)) {
146                 return false;
147             }
148             final Pair other = (Pair) object;
149             return this.parent.equals(other.parent) && this.child.equals(other.child);
150         }
151 
152         @Override
153         public int hashCode() {
154             return this.parent.hashCode() * 37 + this.child.hashCode();
155         }
156 
157     }
158 
159 }