/* * #! * Ontopoly Editor * #- * Copyright (C) 2001 - 2013 The Ontopia Project * #- * 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 ontopoly.model; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import net.ontopia.topicmaps.query.core.DeclarationContextIF; import net.ontopia.topicmaps.query.core.InvalidQueryException; import net.ontopia.topicmaps.query.core.QueryProcessorIF; import net.ontopia.topicmaps.query.core.QueryResultIF; import net.ontopia.topicmaps.query.utils.RowMapperIF; import net.ontopia.utils.OntopiaRuntimeException; public class QueryMapper<T> { private DeclarationContextIF context; private QueryProcessorIF processor; private final RowMapperIF<T> FIRST_COLUMN_MAPPER = new RowMapperIF<T>() { public T mapRow(QueryResultIF queryResult, int rowno) { return wrapValue(queryResult.getValue(0)); } }; public QueryMapper(QueryProcessorIF processor) { this(processor, null); } public QueryMapper(QueryProcessorIF processor, DeclarationContextIF context) { this.processor = processor; this.context = context; } /** * EXPERIMENTAL: Returns true if the query produces a row and * false if the query produces no rows. */ public boolean isTrue(String query) { return isTrue(query, null); } /** * EXPERIMENTAL: Returns true if the query produces a row and * false if the query produces no rows. */ public boolean isTrue(String query, Map<String,?> params) { QueryResultIF result = null; try { result = execute(query, params); return result.next(); } catch (InvalidQueryException e) { throw new OntopiaRuntimeException(e); } finally { if (result != null) result.close(); } } /** * EXPERIMENTAL: Returns the value in the first column in the first * row of the query result. If the query produces no results null is * returned. */ public T queryForObject(String query) { return queryForObject(query, FIRST_COLUMN_MAPPER, null); } /** * EXPERIMENTAL: Returns the value in the first column in the first * row of the query result. If the query produces no results null is * returned. */ public T queryForObject(String query, Map<String,?> params) { return queryForObject(query, FIRST_COLUMN_MAPPER, params); } /** * EXPERIMENTAL: Returns the value in the first column in the first * row of the query result. If the query produces no results null is * returned. */ public T queryForObject(String query, RowMapperIF<T> mapper) { return queryForObject(query, mapper, null); } /** * EXPERIMENTAL: Returns the mapping of the value in the first * column in the first row of the query result. If the query * produces no results null is returned. */ public T queryForObject(String query, RowMapperIF<T> mapper, Map<String,?> params) { QueryResultIF result = null; try { result = execute(query, params); int ix=0; if (result.next()) return mapper.mapRow(result, ix++); else return null; } catch (InvalidQueryException e) { throw new OntopiaRuntimeException(e); } finally { if (result != null) result.close(); } } /** * EXPERIMENTAL: Runs the query, and returns a the single value in * each row. */ public List<T> queryForList(String query) { return queryForList(query, FIRST_COLUMN_MAPPER, null); } /** * EXPERIMENTAL: Runs the query, and calls the mapper for each row * in the query result. Returns a list of all the objects produced * by the mapper in query result order. */ public List<T> queryForList(String query, RowMapperIF<T> mapper) { return queryForList(query, mapper, null); } /** * EXPERIMENTAL: Runs the query, and returns a the single value in * each row. */ public List<T> queryForList(String query, Map<String,?> params) { return queryForList(query, FIRST_COLUMN_MAPPER, params); } /** * EXPERIMENTAL: Runs the query with the given parameters, and calls * the mapper for each row in the query result. Returns a list of * all the objects produced by the mapper in query result order. */ public List<T> queryForList(String query, RowMapperIF<T> mapper, Map<String,?> params) { List<T> list = new ArrayList<T>(); QueryResultIF result = null; try { result = execute(query, params); int ix = 0; while (result.next()) list.add(mapper.mapRow(result, ix++)); } catch (InvalidQueryException e) { throw new OntopiaRuntimeException(e); } finally { if (result != null) result.close(); } return list; } /** * EXPERIMENTAL: Returns a map of the first row of the query * results, with each variable name (without $) as a key and each * variable value as the value of the key. If the query produces no * rows the method returns null; if it produces more than one an * exception is thrown. */ public Map<String,T> queryForMap(String query) { return queryForMap(query, null); } /** * EXPERIMENTAL: Returns a map of the first row of the query * results, with each variable name (without $) as a key and each * variable value as the value of the key. If the query produces no * rows the method returns null. */ public Map<String,T> queryForMap(String query, Map<String,?> params) { QueryResultIF result = null; try { result = execute(query, params); if (result.next()) { Map<String,T> row = new HashMap<String,T>(result.getWidth()); for (int ix = 0; ix < result.getWidth(); ix++) row.put(result.getColumnName(ix), wrapValue(result.getValue(ix))); return row; } else { return null; } } catch (InvalidQueryException e) { throw new OntopiaRuntimeException(e); } finally { if (result != null) result.close(); } } @SuppressWarnings("unchecked") protected T wrapValue(Object value) { return (T)value; } protected QueryResultIF execute(String query, Map<String,?> params) throws InvalidQueryException { return (params == null ? processor.execute(query, context) : processor.execute(query, params, context)); } }