/* * Copyright (c) 2017 OBiBa. All rights reserved. * * This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.obiba.magma.datasource.limesurvey; import java.sql.ResultSet; import java.sql.SQLException; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.springframework.jdbc.core.RowCallbackHandler; import org.springframework.jdbc.support.rowset.SqlRowSet; import com.google.common.collect.Lists; import com.google.common.collect.Maps; public class LimesurveyElementProviderJdbc implements LimesurveyElementProvider { private final LimesurveyDatasource datasource; private final int sid; private final Map<Integer, LimeQuestion> mapQuestions; private final Map<Integer, List<LimeAnswer>> mapAnswers; private final Map<Integer, LimeAttributes> mapAttributes; public LimesurveyElementProviderJdbc(LimesurveyDatasource datasource, int sid) { this.datasource = datasource; this.sid = sid; mapQuestions = new LinkedHashMap<>(); mapAnswers = Maps.newHashMap(); mapAttributes = Maps.newHashMap(); } @Override public Map<Integer, LimeQuestion> queryQuestions() { String sqlQuestion = "SELECT * FROM " + datasource.quoteAndPrefix("questions") + " q JOIN " + datasource.quoteAndPrefix("groups") + " g " // + "ON (q.gid=g.gid AND q.language=g.language) " // + "WHERE q.sid=? AND q.type!='X' " // X are boilerplate questions + "ORDER BY group_order, question_order ASC "; SqlRowSet questionsRowSet = datasource.getJdbcTemplate().queryForRowSet(sqlQuestion, sid); return toQuestions(questionsRowSet); } @Override public Map<Integer, List<LimeAnswer>> queryExplicitAnswers() { String sqlAnswer = "SELECT * FROM " + datasource.quoteAndPrefix("answers") + " WHERE qid=? ORDER BY sortorder"; for(LimeQuestion question : mapQuestions.values()) { SqlRowSet answersRowset = datasource.getJdbcTemplate().queryForRowSet(sqlAnswer, question.getQid()); List<LimeAnswer> answersList = toAnswers(question, answersRowset); mapAnswers.put(question.getQid(), answersList); } return mapAnswers; } @Override public Map<Integer, LimeAttributes> queryAttributes() { SqlRowSet sqlRowSet = datasource.getJdbcTemplate() .queryForRowSet("SELECT qid, attribute, value FROM " + datasource.quoteAndPrefix("question_attributes")); while(sqlRowSet.next()) { int qid = sqlRowSet.getInt("qid"); String key = sqlRowSet.getString("attribute"); String value = sqlRowSet.getString("value"); if(mapAttributes.containsKey(qid)) { mapAttributes.get(qid).attribute(key, value); } else { mapAttributes.put(qid, LimeAttributes.create().attribute(key, value)); } } datasource.getJdbcTemplate() .query("SELECT qid, help, language FROM " + datasource.quoteAndPrefix("questions"), new RowCallbackHandler() { @Override public void processRow(ResultSet rs) throws SQLException { String help = rs.getString("help"); int qid = rs.getInt("qid"); String key = "help:" + rs.getString("language"); if(mapAttributes.containsKey(qid)) { mapAttributes.get(qid).attribute(key, help); } else { mapAttributes.put(qid, LimeAttributes.create().attribute(key, help)); } } }); return mapAttributes; } private Map<Integer, LimeQuestion> toQuestions(SqlRowSet rows) { while(rows.next()) { int qid = rows.getInt("qid"); String language = rows.getString("language"); if(mapQuestions.containsKey(qid)) { LimeQuestion question = mapQuestions.get(qid); question.addLocalizableAttribute("label:" + language, rows.getString("question")); } else { LimeQuestion question = LimeQuestion.create(); question.setName(rows.getString("title")); question.setQid(qid); question.setGroupId(rows.getInt("gid")); question.setParentQid(rows.getInt("parent_qid")); question.setType(LimesurveyType._valueOf(rows.getString("type"))); question.addLocalizableAttribute("label:" + language, rows.getString("question")); question.setUseOther("Y".equals(rows.getString("other"))); question.setScaleId(rows.getInt("scale_id")); mapQuestions.put(qid, question); } } return mapQuestions; } @SuppressWarnings("PMD.NcssMethodCount") private List<LimeAnswer> toAnswers(LimeQuestion question, SqlRowSet rows) { List<LimeAnswer> answers = Lists.newArrayList(); Map<String, LimeAnswer> internAnswers = Maps.newHashMap(); while(rows.next()) { String answerName = rows.getString("code"); String language = rows.getString("language"); String label = rows.getString("answer"); Integer scaleId = rows.getInt("scale_id"); if(internAnswers.containsKey(answerName + scaleId)) { LimeAnswer answer = internAnswers.get(answerName + scaleId); answer.addLocalizableAttribute("label:" + language, label); } else { LimeAnswer answer = LimeAnswer.create(answerName); answer.setSortorder(rows.getInt("sortorder")); answer.setScaleId(rows.getInt("scale_id")); answer.addLocalizableAttribute("label:" + language, label); internAnswers.put(answerName + scaleId, answer); answers.add(answer); } } if(question.isUseOther()) { LimeAnswer answer = LimeAnswer.create("-oth-"); answers.add(answer); } return answers; } }