/* * This file is a part of EpnTAPClient. * This program aims to provide EPN-TAP support for software clients, like CASSIS spectrum analyzer. * See draft specifications: https://voparis-confluence.obspm.fr/pages/viewpage.action?pageId=559861 * Copyright (C) 2016 Institut de Recherche en Astrophysique et Planétologie. * * This program is free software: you can * redistribute it and/or modify it under the terms of the GNU General Public License as published * by the Free Software Foundation, either version 3 of the License, or (at your option) any later * version. This program is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. You should have received a copy of * the GNU General Public License along with this program. If not, see * . */ package eu.omp.irap.vespa.epntapclient; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Logger; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import eu.omp.irap.vespa.votable.utils.CantSendQueryException; import eu.omp.irap.vespa.votable.utils.Network; import eu.omp.irap.vespa.votable.utils.StringJoiner; /** * @author N. Jourdane */ public class RequestCtrl { /** The text in the query to replaced by the actual table name. */ private static final String KEYWORD_TABLE_NAME_ = "#tablename#"; /** The logger for the class RequestCtrl. */ private static final Logger LOGGER = Logger.getLogger(RequestCtrl.class.getName()); /** The query template to get granules. */ private static final String QUERY_TEMPLATE = "SELECT DISTINCT TOP %s %s FROM " + KEYWORD_TABLE_NAME_ + "%s"; /** The URL of the resolver used for the `target name` field. */ private static final String RESOLVER_URL = "http://voparis-registry.obspm.fr/ssodnet/1/autocomplete"; /** The names of the columns used in the SELECT keyword in the query. */ protected List columnNames; /** The maximum number of rows returned by the query. */ protected int nbMaxResult; /** The parameters fields for the request. */ protected Map parameters = new HashMap<>(); /** * The query to send, with the name of the table is replaced by {@link #KEYWORD_TABLE_NAME_}. */ protected String query; /** Default constructor of RequestCtrl. */ public RequestCtrl() { List newColumnNames = new ArrayList<>(); newColumnNames.add("target_name"); newColumnNames.add("target_class"); columnNames = newColumnNames; nbMaxResult = 20; } /** * Constructor of RequestCtrl. * * @param nbMaxResult The maximum number of rows returned by the query. */ public RequestCtrl(int nbMaxResult, List columnNames) { this.nbMaxResult = nbMaxResult; this.columnNames = columnNames; } /** * The method used to get target names propositions by asking to the resolver. * * @param begining The beginning of the target_name. * @return An array of Strings corresponding to the target names got. * @throws CantSendQueryException Can not read the JSON file. */ public static String[] getTargetNames(String begining) throws CantSendQueryException { Map params = new HashMap<>(); params.put("q", "\"" + begining + "\""); String query = Network.buildGetRequest(RESOLVER_URL, params); JsonObject root = Network.readJson(query); int count = Integer.parseInt(root.get("count").toString()); String[] targetNames = new String[count]; JsonArray hits = root.getAsJsonArray("hits"); for (int i = 0; i < count; i++) { JsonObject elmt = hits.get(i).getAsJsonObject(); targetNames[i] = elmt.get("name").toString().replace("\"", ""); } return targetNames; } public List getColumnNames() { return columnNames; } /** * @return The maximum number of rows returned by the query. */ public int getNbMaxResult() { return nbMaxResult; } /** * Get the parameters. * * @return A map of couple . */ public Map getParameters() { return parameters; } public String getQuery(String tableName) { return query.replace(KEYWORD_TABLE_NAME_, tableName); } /** * Remove a parameter from the query. * * @param paramName The name of the parameter to remove. */ public void removeParameter(String paramName) { parameters.remove(paramName); LOGGER.info("removed " + paramName); } public void setColumnNames(List columnNames) { this.columnNames = columnNames; } /** * Set the maximum number of rows returned by the query. * * @param nbRows The number of rows. */ public void setNbMaxResult(int nbRows) { nbMaxResult = nbRows; } public void setQuery(String query) { this.query = query; } /** * Update a parameter in the query. If the parameter do not exists yet, create it. * * @param paramName The name of the parameter. * @param paramValue The value of the parameter. */ public void updateParameter(String paramName, Object paramValue) { parameters.put(paramName, paramValue); LOGGER.info("updated " + paramName + ": " + paramValue); } /** * Update the ADQL query, from the column names, the table name, the parameter values and the * max results. */ public void updateQuery() { StringJoiner addJoin = new StringJoiner(" AND "); for (Map.Entry param : parameters.entrySet()) { if (param.getValue() instanceof ArrayList) { StringJoiner orJoin = new StringJoiner(" OR "); @SuppressWarnings("unchecked") List possibleValues = (List) param.getValue(); for (String possibleValue : possibleValues) { orJoin.add(param.getKey() + " LIKE '" + possibleValue + "'"); } addJoin.add("(" + orJoin + ")"); } else if (param.getValue() instanceof String) { addJoin.add(param.getKey() + " LIKE '" + param.getValue() + "'"); } else { addJoin.add(param.getKey() + " = " + param.getValue().toString()); } } String where = addJoin.isEmpty() ? "" : " WHERE " + addJoin; query = String.format(QUERY_TEMPLATE, nbMaxResult, StringJoiner.join(columnNames), where); } }