Skip to content

Method: getCurrent(int)

1: /*
2: * JOPA
3: * Copyright (C) 2024 Czech Technical University in Prague
4: *
5: * This library is free software; you can redistribute it and/or
6: * modify it under the terms of the GNU Lesser General Public
7: * License as published by the Free Software Foundation; either
8: * version 3.0 of the License, or (at your option) any later version.
9: *
10: * This library is distributed in the hope that it will be useful,
11: * but WITHOUT ANY WARRANTY; without even the implied warranty of
12: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13: * Lesser General Public License for more details.
14: *
15: * You should have received a copy of the GNU Lesser General Public
16: * License along with this library.
17: */
18: package cz.cvut.kbss.ontodriver.rdf4j.query;
19:
20: import cz.cvut.kbss.jopa.datatype.DatatypeTransformer;
21: import cz.cvut.kbss.jopa.datatype.exception.UnsupportedTypeTransformationException;
22: import cz.cvut.kbss.ontodriver.Statement;
23: import cz.cvut.kbss.ontodriver.exception.OntoDriverException;
24: import cz.cvut.kbss.ontodriver.exception.VariableNotBoundException;
25: import cz.cvut.kbss.ontodriver.rdf4j.exception.Rdf4jDriverException;
26: import cz.cvut.kbss.ontodriver.rdf4j.util.Rdf4jUtils;
27: import org.eclipse.rdf4j.model.IRI;
28: import org.eclipse.rdf4j.model.Literal;
29: import org.eclipse.rdf4j.model.Value;
30: import org.eclipse.rdf4j.query.BindingSet;
31: import org.eclipse.rdf4j.query.QueryEvaluationException;
32: import org.eclipse.rdf4j.query.TupleQueryResult;
33:
34: import java.util.List;
35: import java.util.Objects;
36:
37: // TODO Resolve mapping of data values with language tag
38: public class SelectResultSet extends AbstractResultSet {
39:
40: private final TupleQueryResult result;
41: private List<String> bindings;
42: private BindingSet current;
43:
44: public SelectResultSet(TupleQueryResult result, Statement statement) {
45: super(statement);
46: assert result != null;
47:
48: this.result = result;
49: init();
50: }
51:
52: private void init() {
53: this.bindings = result.getBindingNames();
54: }
55:
56: @Override
57: public void close() throws OntoDriverException {
58: try {
59: result.close();
60: } catch (QueryEvaluationException e) {
61: throw new OntoDriverException(e);
62: } finally {
63: super.close();
64: }
65: }
66:
67: @Override
68: public int findColumn(String columnLabel) {
69: ensureOpen();
70: return bindings.indexOf(columnLabel);
71: }
72:
73: @Override
74: public int getColumnCount() {
75: ensureOpen();
76: return bindings.size();
77: }
78:
79: @Override
80: public boolean isBound(int variableIndex) {
81: return variableIndex >= 0 && variableIndex < bindings.size() && current
82: .getValue(bindings.get(variableIndex)) != null;
83: }
84:
85: @Override
86: public boolean isBound(String variableName) {
87: Objects.requireNonNull(variableName);
88: return bindings.contains(variableName) && current.getValue(variableName) != null;
89: }
90:
91: @Override
92: public boolean getBoolean(int columnIndex) throws OntoDriverException {
93: ensureOpen();
94: return toBoolean(getLiteralValue(columnIndex));
95: }
96:
97: @Override
98: public boolean getBoolean(String columnLabel) throws OntoDriverException {
99: ensureOpen();
100: return toBoolean(getLiteralValue(columnLabel));
101: }
102:
103: private static boolean toBoolean(Object ob) {
104: if (ob instanceof Boolean) {
105: return (boolean) ob;
106: } else {
107: return Boolean.parseBoolean(ob.toString());
108: }
109: }
110:
111: @Override
112: public byte getByte(int columnIndex) throws OntoDriverException {
113: ensureOpen();
114: return (byte) toInt(getLiteralValue(columnIndex));
115: }
116:
117: @Override
118: public byte getByte(String columnLabel) throws OntoDriverException {
119: ensureOpen();
120: return (byte) toInt(getLiteralValue(columnLabel));
121: }
122:
123: @Override
124: public double getDouble(int columnIndex) throws OntoDriverException {
125: ensureOpen();
126: return toDouble(getLiteralValue(columnIndex));
127: }
128:
129: @Override
130: public double getDouble(String columnLabel) throws OntoDriverException {
131: ensureOpen();
132: return toDouble(getLiteralValue(columnLabel));
133: }
134:
135: private static double toDouble(Object ob) throws OntoDriverException {
136: if (ob instanceof Number) {
137: return ((Number) ob).doubleValue();
138: } else {
139: try {
140: return Double.parseDouble(ob.toString());
141: } catch (NumberFormatException e) {
142: throw new OntoDriverException(e);
143: }
144: }
145: }
146:
147: @Override
148: public float getFloat(int columnIndex) throws OntoDriverException {
149: ensureOpen();
150: return toFloat(getLiteralValue(columnIndex));
151: }
152:
153: @Override
154: public float getFloat(String columnLabel) throws OntoDriverException {
155: ensureOpen();
156: return toFloat(getLiteralValue(columnLabel));
157: }
158:
159: private static float toFloat(Object ob) throws OntoDriverException {
160: if (ob instanceof Number) {
161: return ((Number) ob).floatValue();
162: } else {
163: try {
164: return Float.parseFloat(ob.toString());
165: } catch (NumberFormatException e) {
166: throw new OntoDriverException(e);
167: }
168: }
169: }
170:
171: @Override
172: public int getInt(int columnIndex) throws OntoDriverException {
173: ensureOpen();
174: return toInt(getLiteralValue(columnIndex));
175: }
176:
177: @Override
178: public int getInt(String columnLabel) throws OntoDriverException {
179: ensureOpen();
180: return toInt(getLiteralValue(columnLabel));
181: }
182:
183: private static int toInt(Object ob) throws OntoDriverException {
184: if (ob instanceof Number) {
185: return ((Number) ob).intValue();
186: } else {
187: try {
188: return Integer.parseInt(ob.toString());
189: } catch (NumberFormatException e) {
190: throw new OntoDriverException(e);
191: }
192: }
193: }
194:
195: @Override
196: public long getLong(int columnIndex) throws OntoDriverException {
197: ensureOpen();
198: return toLong(getLiteralValue(columnIndex));
199: }
200:
201: @Override
202: public long getLong(String columnLabel) throws OntoDriverException {
203: ensureOpen();
204: return toLong(getLiteralValue(columnLabel));
205: }
206:
207: private static long toLong(Object ob) throws OntoDriverException {
208: if (ob instanceof Number) {
209: return ((Number) ob).longValue();
210: } else {
211: try {
212: return Long.parseLong(ob.toString());
213: } catch (NumberFormatException e) {
214: throw new OntoDriverException(e);
215: }
216: }
217: }
218:
219: @Override
220: public Object getObject(int columnIndex) {
221: ensureOpen();
222: return toObject(getCurrent(columnIndex));
223: }
224:
225: @Override
226: public Object getObject(String columnLabel) {
227: ensureOpen();
228: return toObject(getCurrent(columnLabel));
229: }
230:
231: private static Object toObject(Value val) {
232: assert val != null;
233: if (val instanceof Literal) {
234: return Rdf4jUtils.getLiteralValue((Literal) val);
235: } else if (val instanceof IRI) {
236: return Rdf4jUtils.toJavaUri((IRI) val);
237: } else {
238: return val.toString();
239: }
240: }
241:
242: @Override
243: public <T> T getObject(int columnIndex, Class<T> cls) throws OntoDriverException {
244: ensureOpen();
245: return toObject(getCurrent(columnIndex), cls);
246: }
247:
248: @Override
249: public <T> T getObject(String columnLabel, Class<T> cls) throws OntoDriverException {
250: ensureOpen();
251: return toObject(getCurrent(columnLabel), cls);
252: }
253:
254: private static <T> T toObject(Value val, Class<T> cls) throws OntoDriverException {
255: assert val != null;
256: if (cls.isAssignableFrom(val.getClass())) {
257: return cls.cast(val);
258: }
259: Object ob = null;
260: if (val instanceof Literal) {
261: ob = Rdf4jUtils.getLiteralValue((Literal) val);
262: } else if (val instanceof IRI) {
263: ob = Rdf4jUtils.toJavaUri((IRI) val);
264: }
265: try {
266: return cls.cast(DatatypeTransformer.transform(ob, cls));
267: } catch (UnsupportedTypeTransformationException e) {
268: throw new Rdf4jDriverException("Unable to transform value to target object.", e);
269: }
270: }
271:
272: @Override
273: public short getShort(int columnIndex) throws OntoDriverException {
274: ensureOpen();
275: return (short) toInt(getLiteralValue(columnIndex));
276: }
277:
278: @Override
279: public short getShort(String columnLabel) throws OntoDriverException {
280: ensureOpen();
281: return (short) toInt(getLiteralValue(columnLabel));
282: }
283:
284: @Override
285: public String getString(int columnIndex) {
286: ensureOpen();
287: return getStringImpl(getCurrent(columnIndex));
288: }
289:
290: @Override
291: public String getString(String columnLabel) {
292: ensureOpen();
293: return getStringImpl(getCurrent(columnLabel));
294: }
295:
296: private static String getStringImpl(Value val) {
297: if (val instanceof Literal) {
298: return Rdf4jUtils.getLiteralValue((Literal) val).toString();
299: } else {
300: return val.toString();
301: }
302: }
303:
304: @Override
305: public boolean hasNext() throws OntoDriverException {
306: ensureOpen();
307: try {
308: return result.hasNext();
309: } catch (QueryEvaluationException e) {
310: throw new OntoDriverException(e);
311: }
312: }
313:
314: @Override
315: public void next() throws OntoDriverException {
316: super.next();
317: try {
318: this.current = result.next();
319: } catch (QueryEvaluationException e) {
320: throw new OntoDriverException(e);
321: }
322: }
323:
324: private Object getLiteralValue(int columnIndex) throws OntoDriverException {
325: final Value val = getCurrent(columnIndex);
326: if (!(val instanceof Literal)) {
327: throw new OntoDriverException("Expected value " + val + " to be a literal.");
328: }
329: return Rdf4jUtils.getLiteralValue((Literal) val);
330: }
331:
332: private Object getLiteralValue(String columnName) throws OntoDriverException {
333: final Value val = getCurrent(columnName);
334: if (!(val instanceof Literal)) {
335: throw new OntoDriverException("Expected value " + val + " to be a literal.");
336: }
337: return Rdf4jUtils.getLiteralValue((Literal) val);
338: }
339:
340: private Value getCurrent(int columnIndex) {
341: ensureState();
342:• if (columnIndex < 0 || columnIndex >= bindings.size()) {
343: throw new IllegalArgumentException(
344: "The column index is out of bounds of the column count.");
345: }
346: final Value v = current.getValue(bindings.get(columnIndex));
347:• if (v == null) {
348: throw new VariableNotBoundException(
349: "Variable at index " + columnIndex + " is not bound in the current result row.");
350: }
351: return v;
352: }
353:
354: private void ensureState() {
355: if (current == null) {
356: throw new IllegalStateException("Must call next before getting the first value.");
357: }
358: }
359:
360: private Value getCurrent(String columnName) {
361: ensureState();
362: if (!bindings.contains(columnName)) {
363: throw new IllegalArgumentException("Unknown column name " + columnName);
364: }
365: final Value v = current.getValue(columnName);
366: if (v == null) {
367: throw new VariableNotBoundException(
368: "Variable \"" + columnName + "\" is not bound in the current result row.");
369: }
370: return v;
371: }
372: }