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