Java tutorial
/* * Copyright (c) 2018 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.mica.dataset.search.rest; import java.io.IOException; import java.io.InputStream; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; import javax.annotation.Nullable; import javax.inject.Inject; import javax.validation.constraints.NotNull; import org.obiba.magma.NoSuchVariableException; import org.obiba.mica.core.domain.BaseStudyTable; import org.obiba.mica.core.domain.OpalTable; import org.obiba.mica.core.domain.StudyTable; import org.obiba.mica.dataset.NoSuchDatasetException; import org.obiba.mica.dataset.domain.Dataset; import org.obiba.mica.dataset.domain.DatasetVariable; import org.obiba.mica.dataset.domain.HarmonizationDataset; import org.obiba.mica.micaConfig.service.OpalService; import org.obiba.mica.spi.search.Indexer; import org.obiba.mica.spi.search.Searcher; import org.obiba.mica.web.model.Dtos; import org.obiba.mica.web.model.Mica; import org.obiba.opal.core.domain.taxonomy.Taxonomy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Strings; /** * Retrieve the {@link org.obiba.mica.dataset.domain.Dataset} from the published dataset index. * * @param <T> */ public abstract class AbstractPublishedDatasetResource<T extends Dataset> { private static final Logger log = LoggerFactory.getLogger(AbstractPublishedDatasetResource.class); @Inject protected ApplicationContext applicationContext; @Inject protected Dtos dtos; @Inject protected Searcher searcher; @Inject protected ObjectMapper objectMapper; @Inject protected OpalService opalService; private String locale; protected T getDataset(Class<T> clazz, @NotNull String datasetId) throws NoSuchDatasetException { InputStream inputStream = searcher.getDocumentByClassName(Indexer.PUBLISHED_DATASET_INDEX, Indexer.DATASET_TYPE, clazz, datasetId); if (inputStream == null) throw NoSuchDatasetException.withId(datasetId); try { T rval = objectMapper.readValue(inputStream, clazz); log.info("Response /{}/{}", Indexer.PUBLISHED_DATASET_INDEX, Indexer.DATASET_TYPE); return rval; } catch (IOException e) { log.error("Failed retrieving {}", clazz.getSimpleName(), e); throw NoSuchDatasetException.withId(datasetId); } } protected Mica.DatasetDto getDatasetDto(Class<T> clazz, @NotNull String datasetId) throws NoSuchDatasetException { return dtos.asDto(getDataset(clazz, datasetId)); } protected Mica.DatasetVariablesDto getDatasetVariableDtos(@NotNull String queryString, @NotNull String datasetId, DatasetVariable.Type type, int from, int limit, @Nullable String sort, @Nullable String order) { // TODO make a helper class for this String queryStr = ""; if (!Strings.isNullOrEmpty(queryString)) { queryStr = String.format(",query(%s)", queryString.replaceAll(" ", "+")); } String rql = String.format("and(eq(datasetId,%s),eq(variableType,%s)%s)", datasetId, type.toString(), queryStr); return getDatasetVariableDtosInternal(rql, from, limit, sort, order); } protected Mica.DatasetVariablesDto getDatasetVariableDtos(@NotNull String datasetId, DatasetVariable.Type type, int from, int limit, @Nullable String sort, @Nullable String order) { String rql = String.format("and(eq(datasetId,%s),eq(variableType,%s))", datasetId, type.toString()); return getDatasetVariableDtosInternal(rql, from, limit, sort, order); } protected Mica.DatasetVariablesDto getDatasetVariableDtosInternal(String rql, int from, int limit, @Nullable String sort, @Nullable String order) { String rqlSort = ""; if (!Strings.isNullOrEmpty(sort)) { String orderOp = !Strings.isNullOrEmpty(order) && "DESC".equals(order.toUpperCase()) ? "-" : ""; rqlSort = String.format(",sort(%s)", orderOp + sort); } String query = String.format("variable(%s,limit(%s,%s)%s)", rql, from, limit, rqlSort); Searcher.DocumentResults results = searcher.find(Indexer.PUBLISHED_VARIABLE_INDEX, Indexer.VARIABLE_TYPE, query); Mica.DatasetVariablesDto.Builder builder = Mica.DatasetVariablesDto.newBuilder() .setTotal(Long.valueOf(results.getTotal()).intValue()).setFrom(from).setLimit(limit); List<Taxonomy> taxonomies = getTaxonomies(); Map<String, List<DatasetVariable>> studyIdVariableMap = results.getDocuments().stream().map(res -> { try { return objectMapper.readValue(res.getSourceInputStream(), DatasetVariable.class); } catch (IOException e) { log.error("Failed retrieving {}", DatasetVariable.class.getSimpleName(), e); return null; } }).filter(Objects::nonNull).collect(Collectors.groupingBy(DatasetVariable::getStudyId)); builder.addAllVariables(dtos.asDtos(studyIdVariableMap, taxonomies)); log.info("Response /{}/{}", Indexer.PUBLISHED_VARIABLE_INDEX, Indexer.VARIABLE_TYPE); return builder.build(); } protected Mica.DatasetVariableHarmonizationDto getVariableHarmonizationDto(HarmonizationDataset dataset, String variableName, boolean includeSummaries) { DatasetVariable.IdResolver variableResolver = DatasetVariable.IdResolver.from(dataset.getId(), variableName, DatasetVariable.Type.Dataschema); Mica.DatasetVariableHarmonizationDto.Builder builder = Mica.DatasetVariableHarmonizationDto.newBuilder(); builder.setResolver(dtos.asDto(variableResolver)); dataset.getBaseStudyTables().forEach(table -> { try { builder.addDatasetVariableSummaries(getDatasetVariableSummaryDto(dataset.getId(), variableResolver.getName(), DatasetVariable.Type.Harmonized, table, includeSummaries)); } catch (NoSuchVariableException e) { log.debug("ignore (case the study has not implemented this dataschema variable)", e); } }); return builder.build(); } protected DatasetVariable getDatasetVariable(@NotNull String datasetId, @NotNull String variableName, DatasetVariable.Type variableType, OpalTable opalTable) { if (opalTable != null) { return getDatasetVariable(datasetId, variableName, variableType, opalTable instanceof BaseStudyTable ? ((BaseStudyTable) opalTable).getStudyId() : null, opalTable.getProject(), opalTable.getTable(), opalTable instanceof StudyTable ? DatasetVariable.OPAL_STUDY_TABLE_PREFIX : DatasetVariable.OPAL_HARMONIZATION_TABLE_PREFIX); } return getDatasetVariable(datasetId, variableName, variableType, null, null, null, null); } /** * Look for a variable of a dataset in the published dataset index or the published study index depending on * whether a study ID is provided for resolving variable's parent. * * @param datasetId * @param variableName * @param studyId * @param project * @param table * @return * @throws NoSuchVariableException */ protected DatasetVariable getDatasetVariable(@NotNull String datasetId, @NotNull String variableName, DatasetVariable.Type variableType, @Nullable String studyId, @Nullable String project, @Nullable String table, @Nullable String tableType) throws NoSuchVariableException { String variableId = DatasetVariable.IdResolver.encode(datasetId, variableName, variableType, studyId, project, table, tableType); if (variableType.equals(DatasetVariable.Type.Harmonized)) { return getHarmonizedDatasetVariable(datasetId, variableId, variableName); } return getDatasetVariableInternal(Indexer.VARIABLE_TYPE, variableId, variableName); } protected Mica.DatasetVariableDto getDatasetVariableDto(@NotNull String datasetId, @NotNull String variableName, DatasetVariable.Type variableType) { return getDatasetVariableDto(datasetId, variableName, variableType, null); } protected Mica.DatasetVariableDto getDatasetVariableDto(@NotNull String datasetId, @NotNull String variableName, DatasetVariable.Type variableType, @Nullable OpalTable opalTable) { return dtos.asDto(getDatasetVariable(datasetId, variableName, variableType, opalTable), getTaxonomies(), getLocale()); } protected Mica.DatasetVariableDto getDatasetVariableDto(@NotNull String datasetId, @NotNull String variableName, DatasetVariable.Type variableType, @Nullable String studyId, @Nullable String project, @Nullable String table, @Nullable String tableType) { return dtos.asDto( getDatasetVariable(datasetId, variableName, variableType, studyId, project, table, tableType), getTaxonomies(), getLocale()); } protected Mica.DatasetVariableSummaryDto getDatasetVariableSummaryDto(@NotNull String datasetId, @NotNull String variableName, DatasetVariable.Type variableType, @Nullable OpalTable opalTable) { DatasetVariable variable = getDatasetVariable(datasetId, variableName, variableType, opalTable); return dtos.asSummaryDto(variable, opalTable, true); } protected Mica.DatasetVariableSummaryDto getDatasetVariableSummaryDto(@NotNull String datasetId, @NotNull String variableName, DatasetVariable.Type variableType, @Nullable OpalTable opalTable, boolean includeSummaries) { DatasetVariable variable = getDatasetVariable(datasetId, variableName, variableType, opalTable); return dtos.asSummaryDto(variable, opalTable, includeSummaries); } @NotNull protected List<Taxonomy> getTaxonomies() { List<Taxonomy> taxonomies = null; try { taxonomies = opalService.getTaxonomies(); } catch (Exception e) { // ignore } return taxonomies == null ? Collections.emptyList() : taxonomies; } private DatasetVariable getHarmonizedDatasetVariable(String datasetId, String variableId, String variableName) { String dataSchemaVariableId = DatasetVariable.IdResolver.encode(datasetId, variableName, DatasetVariable.Type.Dataschema, null, null, null, null); DatasetVariable harmonizedDatasetVariable = getDatasetVariableInternal(Indexer.HARMONIZED_VARIABLE_TYPE, variableId, variableName); DatasetVariable dataSchemaVariable = getDatasetVariableInternal(Indexer.VARIABLE_TYPE, dataSchemaVariableId, variableName); dataSchemaVariable.getAttributes().asAttributeList().forEach(a -> { if (!a.getName().startsWith("Mlstr_harmo")) harmonizedDatasetVariable.addAttribute(a); }); return harmonizedDatasetVariable; } private DatasetVariable getDatasetVariableInternal(String indexType, String variableId, String variableName) { InputStream inputStream = searcher.getDocumentById(Indexer.PUBLISHED_VARIABLE_INDEX, indexType, variableId); if (inputStream == null) throw new NoSuchVariableException(variableName); try { return objectMapper.readValue(inputStream, DatasetVariable.class); } catch (IOException e) { log.error("Failed retrieving {}", DatasetVariable.class.getSimpleName(), e); throw new NoSuchVariableException(variableName); } } public String getLocale() { return locale; } public void setLocale(String value) { locale = value; } }