Skip to content

Commit

Permalink
Merge branch 'development' into feature/#784-evaluate-technical-feasa…
Browse files Browse the repository at this point in the history
…bility-of-tib-terminology-service-integration-for-ontology-terms
  • Loading branch information
sven1103 authored Aug 20, 2024
2 parents 0102fa7 + 4bfe2d9 commit 5930d3b
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 45 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package life.qbic.projectmanagement.domain.model.experiment.repository.jpa;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.persistence.AttributeConverter;
import jakarta.persistence.Converter;
Expand All @@ -11,7 +12,8 @@
public class OntologyClassAttributeConverter implements
AttributeConverter<OntologyTerm, String> {

private static final ObjectMapper objectMapper = new ObjectMapper();
private static final ObjectMapper objectMapper = new ObjectMapper().configure(
DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

@Override
public String convertToDatabaseColumn(OntologyTerm attribute) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
font-weight: normal;
color: #2d2d2d;
font-size: var(--lumo-font-size-s);
white-space: pre-line;
}

.disclaimer .disclaimer-title {
Expand Down
Binary file modified user-interface/src/main/bundles/dev.bundle
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import life.qbic.datamanager.views.projects.project.measurements.download.ProteomicsMeasurementContentProvider;
import life.qbic.logging.api.Logger;
import life.qbic.logging.service.LoggerFactory;
import life.qbic.projectmanagement.application.ProjectInformationService;
import life.qbic.projectmanagement.application.measurement.MeasurementMetadata;
import life.qbic.projectmanagement.application.measurement.MeasurementService;
import life.qbic.projectmanagement.application.measurement.MeasurementService.MeasurementDeletionException;
Expand Down Expand Up @@ -97,6 +98,7 @@ public class MeasurementMain extends Main implements BeforeEnterObserver {
private final NGSMeasurementContentProvider ngsMeasurementContentProvider;
private final DownloadProvider ngsDownloadProvider;
private final DownloadProvider proteomicsDownloadProvider;
private final ProjectInformationService projectInformationService;
private transient Context context;

public MeasurementMain(
Expand All @@ -105,7 +107,8 @@ public MeasurementMain(
@Autowired SampleInformationService sampleInformationService,
@Autowired MeasurementService measurementService,
@Autowired MeasurementPresenter measurementPresenter,
@Autowired MeasurementValidationService measurementValidationService) {
@Autowired MeasurementValidationService measurementValidationService,
ProjectInformationService projectInformationService) {
Objects.requireNonNull(measurementTemplateListComponent);
Objects.requireNonNull(measurementDetailsComponent);
Objects.requireNonNull(measurementService);
Expand Down Expand Up @@ -133,7 +136,8 @@ public MeasurementMain(
add(measurementDetailsComponent);

measurementDetailsComponent.addListener(
selectionChangedEvent -> setSelectedMeasurementsInfo(selectionChangedEvent.getSource().getNumberOfSelectedMeasurements()));
selectionChangedEvent -> setSelectedMeasurementsInfo(
selectionChangedEvent.getSource().getNumberOfSelectedMeasurements()));

add(ngsDownloadProvider);
add(proteomicsDownloadProvider);
Expand All @@ -143,6 +147,7 @@ public MeasurementMain(
getClass().getSimpleName(), System.identityHashCode(this),
measurementTemplateListComponent.getClass().getSimpleName(),
System.identityHashCode(measurementTemplateListComponent)));
this.projectInformationService = projectInformationService;
}

private static String convertErrorCodeToMessage(MeasurementService.ErrorCode errorCode) {
Expand Down Expand Up @@ -203,24 +208,25 @@ private void initSearchFieldAndButtonBar() {

private void onDeleteMeasurementsClicked() {
Optional<String> tabLabel = measurementDetailsComponent.getSelectedTabName();
if(tabLabel.isEmpty()) {
if (tabLabel.isEmpty()) {
return;
}
String label = tabLabel.get();
if(label.equals("Proteomics")) {
if (label.equals("Proteomics")) {
handlePtxDeletionRequest(measurementDetailsComponent.getSelectedProteomicsMeasurements());
}
if(label.equals("Genomics")) {
if (label.equals("Genomics")) {
handleNGSDeletionRequest(measurementDetailsComponent.getSelectedNGSMeasurements());
}
}

private void handlePtxDeletionRequest(Set<ProteomicsMeasurement> measurements) {
if(measurements.isEmpty()) {
if (measurements.isEmpty()) {
return;
}
MeasurementDeletionConfirmationNotification notification =
new MeasurementDeletionConfirmationNotification("Selected proteomics measurements will be deleted", measurements.size());
new MeasurementDeletionConfirmationNotification(
"Selected proteomics measurements will be deleted", measurements.size());
notification.open();
notification.addConfirmListener(event -> {
deletePtxMeasurements(measurements);
Expand All @@ -230,11 +236,12 @@ private void handlePtxDeletionRequest(Set<ProteomicsMeasurement> measurements) {
}

private void handleNGSDeletionRequest(Set<NGSMeasurement> measurements) {
if(measurements.isEmpty()) {
if (measurements.isEmpty()) {
return;
}
MeasurementDeletionConfirmationNotification notification =
new MeasurementDeletionConfirmationNotification("Selected genomics measurements will be deleted", measurements.size());
new MeasurementDeletionConfirmationNotification(
"Selected genomics measurements will be deleted", measurements.size());
notification.open();
notification.addConfirmListener(event -> {
deleteNGSMeasurements(measurements);
Expand All @@ -245,7 +252,7 @@ private void handleNGSDeletionRequest(Set<NGSMeasurement> measurements) {

private void deleteNGSMeasurements(Set<NGSMeasurement> measurements) {
Result<Void, MeasurementDeletionException> result = measurementService.deleteNGSMeasurements(
context.projectId().orElseThrow(), measurements);
context.projectId().orElseThrow(), measurements);
handleDeletionResults(result);
}

Expand Down Expand Up @@ -326,7 +333,7 @@ private void openEditMeasurementDialog() {

private void downloadMetadataForSelectedTab() {
Optional<String> tabLabel = measurementDetailsComponent.getSelectedTabName();
if(tabLabel.isEmpty()) {
if (tabLabel.isEmpty()) {
return;
}
switch (tabLabel.get()) {
Expand Down Expand Up @@ -356,7 +363,9 @@ private void downloadProteomicsMetadata() {
.flatMap(Collection::stream)
.sorted(Comparator.comparing(ProteomicsMeasurementEntry::measurementCode, natOrder)
.thenComparing(ptx -> ptx.sampleInformation().sampleId(), natOrder)).toList();
proteomicsMeasurementContentProvider.setMeasurements(result);
proteomicsMeasurementContentProvider.setMeasurements(result,
projectInformationService.find(context.projectId().orElseThrow()).orElseThrow()
.getProjectCode().value());
proteomicsDownloadProvider.trigger();
}

Expand All @@ -373,7 +382,9 @@ private void downloadNGSMetadata() {
// sort by measurement codes first, then by sample codes
.sorted(Comparator.comparing(NGSMeasurementEntry::measurementCode, natOrder)
.thenComparing(ngs -> ngs.sampleInformation().sampleId(), natOrder)).toList();
ngsMeasurementContentProvider.setMeasurements(result);
ngsMeasurementContentProvider.setMeasurements(result,
projectInformationService.find(context.projectId().orElseThrow()).orElseThrow()
.getProjectCode().value());
ngsDownloadProvider.trigger();
}

Expand Down Expand Up @@ -535,13 +546,13 @@ private void routeToRawData(ComponentEvent<?> componentEvent) {
}

private void setSelectedMeasurementsInfo(int selectedMeasurements) {
String text = "%s measurements are currently selected.".formatted(
String.valueOf(selectedMeasurements));
String text = "%s measurements are currently selected.".formatted(
String.valueOf(selectedMeasurements));
if (selectedMeasurements > 0) {
measurementsSelectedInfoBox.getStyle().setVisibility(Visibility.INITIAL);
} else {
measurementsSelectedInfoBox.getStyle().setVisibility(Visibility.HIDDEN);
}
measurementsSelectedInfoBox.setText(text);
measurementsSelectedInfoBox.setText(text);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,16 @@
*/
public class NGSMeasurementContentProvider implements DownloadContentProvider {

private static final String FILE_NAME = "ngs_measurements.xlsx";
private static final String FILE_NAME_SUFFIX = "ngs_measurements.xlsx";
private static final Logger log = logger(NGSMeasurementContentProvider.class);
private static final byte[] DARK_GREY = {119, 119, 119};
private static final byte[] LIGHT_GREY = {(byte) 220, (byte) 220, (byte) 220};
private static CellStyle readOnlyCellStyle;
private static CellStyle readOnlyHeaderStyle;
private static CellStyle boldStyle;
private final List<NGSMeasurementEntry> measurements = new LinkedList<>();
private static final String DEFAULT_FILE_NAME_PREFIX = "QBiC";
private String fileNamePrefix = DEFAULT_FILE_NAME_PREFIX ;

private static void setAutoWidth(Sheet sheet) {
for (int col = 0; col <= NGSMeasurementColumns.values().length; col++) {
Expand Down Expand Up @@ -135,9 +137,10 @@ private static void createMeasurementEntry(NGSMeasurementEntry ngsMeasurementEnt
setCellStyle(commentCol, NGSMeasurementColumns.COMMENT.readOnly());
}

public void setMeasurements(List<NGSMeasurementEntry> measurements) {
public void setMeasurements(List<NGSMeasurementEntry> measurements, String fileNamePrefix) {
this.measurements.clear();
this.measurements.addAll(measurements);
this.fileNamePrefix = fileNamePrefix.trim();
}

private void defineBoldStyle(Workbook workbook) {
Expand Down Expand Up @@ -207,7 +210,7 @@ public byte[] getContent() {

@Override
public String getFileName() {
return FILE_NAME;
return String.join("_" , fileNamePrefix, FILE_NAME_SUFFIX);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@
*/
public class ProteomicsMeasurementContentProvider implements DownloadContentProvider {

private static final String FILE_NAME = "proteomics_measurements.xlsx";
private static final String FILE_NAME_SUFFIX = "proteomics_measurements.xlsx";
private static final Logger log = logger(ProteomicsMeasurementContentProvider.class);
private static final byte[] DARK_GREY = {119, 119, 119};
private static final byte[] LIGHT_GREY = {(byte) 220, (byte) 220, (byte) 220};
private final List<ProteomicsMeasurementEntry> measurements = new LinkedList<>();
private static final String DEFAULT_FILE_NAME_PREFIX = "QBiC";
private String fileNamePrefix = DEFAULT_FILE_NAME_PREFIX;

private static void setAutoWidth(Sheet sheet) {
for (int col = 0; col <= 18; col++) {
Expand Down Expand Up @@ -139,9 +141,10 @@ private static void createMeasurementEntry(ProteomicsMeasurementEntry pxpEntry,
entry.createCell(18).setCellValue(pxpEntry.comment());
}

public void setMeasurements(List<ProteomicsMeasurementEntry> measurements) {
public void setMeasurements(List<ProteomicsMeasurementEntry> measurements, String fileNamePrefix) {
this.measurements.clear();
this.measurements.addAll(measurements);
this.fileNamePrefix = fileNamePrefix;
}

@Override
Expand Down Expand Up @@ -202,6 +205,6 @@ public byte[] getContent() {

@Override
public String getFileName() {
return FILE_NAME;
return String.join("_", fileNamePrefix, FILE_NAME_SUFFIX);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import life.qbic.datamanager.views.projects.project.experiments.ExperimentMainLayout;
import life.qbic.logging.api.Logger;
import life.qbic.logging.service.LoggerFactory;
import life.qbic.projectmanagement.application.ProjectInformationService;
import life.qbic.projectmanagement.application.dataset.RawDataService;
import life.qbic.projectmanagement.application.experiment.ExperimentInformationService;
import life.qbic.projectmanagement.application.measurement.MeasurementMetadata;
Expand Down Expand Up @@ -73,21 +74,27 @@ public class RawDataMain extends Main implements BeforeEnterObserver {
private final Disclaimer registerMeasurementsDisclaimer;
private final Disclaimer noRawDataRegisteredDisclaimer;
private final String rawDataSourceURL;
private final String documentationUrl;
private final ProjectInformationService projectInformationService;
private transient Context context;

public RawDataMain(@Autowired RawDataDetailsComponent rawDataDetailsComponent,
@Autowired RawDataDownloadInformationComponent rawDataDownloadInformationComponent,
@Autowired ExperimentInformationService experimentInformationService,
@Autowired MeasurementService measurementService,
@Autowired RawDataService rawDataService,
@Value("${server.download.api.measurement.url}") String dataSourceURL) {
@Value("${server.download.api.measurement.url}") String dataSourceURL,
@Value("${qbic.communication.documentation.url}") String documentationUrl,
@Autowired ProjectInformationService projectInformationService) {
this.projectInformationService = Objects.requireNonNull(projectInformationService);
this.rawdataDetailsComponent = Objects.requireNonNull(rawDataDetailsComponent);
this.rawDataDownloadInformationComponent = Objects.requireNonNull(
rawDataDownloadInformationComponent);
this.experimentInformationService = Objects.requireNonNull(experimentInformationService);
this.measurementService = Objects.requireNonNull(measurementService);
this.rawDataService = Objects.requireNonNull(rawDataService);
this.rawDataSourceURL = Objects.requireNonNull(dataSourceURL);
this.documentationUrl = Objects.requireNonNull(documentationUrl);
registerMeasurementsDisclaimer = createNoMeasurementsRegisteredDisclaimer();
registerMeasurementsDisclaimer.addClassName("no-measurements-registered-disclaimer");
noRawDataRegisteredDisclaimer = createNoRawDataRegisteredDisclaimer();
Expand Down Expand Up @@ -157,7 +164,10 @@ private void handleUrlDownload(ComponentEvent<?> event) {
var currentExperiment = experimentInformationService.find(
context.projectId().orElseThrow().value(), context.experimentId().orElseThrow())
.orElseThrow();
urlDownloadFormatter.updateContext(currentExperiment, downloadUrls);
var currentProjectCode = projectInformationService.find(context.projectId().orElseThrow())
.orElseThrow().getProjectCode().value();
urlDownloadFormatter.updateContext(downloadUrls,
String.join("_", currentProjectCode, currentExperiment.getName().replace(" ", "_")));
urlDownload.trigger();
}

Expand Down Expand Up @@ -242,14 +252,22 @@ private Disclaimer createNoMeasurementsRegisteredDisclaimer() {

private Disclaimer createNoRawDataRegisteredDisclaimer() {
Disclaimer noRawDataRegistered = Disclaimer.createWithTitle(
"No Raw Data available",
"There is currently no raw data registered for the measurements within this experiment",
"Register Measurements");
"Register your raw data first",
"Raw data should be registered before you can view and download raw data files.\n"
+ "You can refer to our documentation to register raw data for your measurements.",
"View Documentation");
noRawDataRegistered.addDisclaimerConfirmedListener(
this::routeToMeasurementCreation);
this::routeToRawDataDocumentation);
return noRawDataRegistered;
}

private void routeToRawDataDocumentation(ComponentEvent<?> componentEvent) {
if (componentEvent.isFromClient()) {
componentEvent.getSource().getUI().ifPresent(ui -> ui.getPage()
.open(documentationUrl, "_blank"));
}
}

private void routeToMeasurementCreation(ComponentEvent<?> componentEvent) {
if (componentEvent.isFromClient()) {
String currentExperimentId = context.experimentId().orElseThrow().value();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public class RawDataURLContentProvider implements DownloadContentProvider {
private Experiment experiment;
private List<RawDataURL> rawDataUrls;
private static final String FILE_SUFFIX = "rawdata_urls.txt";
private static final String DEFAULT_FILE_PREFIX = "QBiC";
private String fileNamePrefix = DEFAULT_FILE_PREFIX;

@Override
public byte[] getContent() {
Expand All @@ -28,22 +30,14 @@ public byte[] getContent() {
return textFileBuilder.getRowString().getBytes(StandardCharsets.UTF_8);
}

public void updateContext(Experiment experiment, List<RawDataURL> rawDataUrls) {
this.experiment = experiment;
public void updateContext(List<RawDataURL> rawDataUrls, String fileNamePrefix) {
this.fileNamePrefix = fileNamePrefix;
this.rawDataUrls = rawDataUrls;
}

/**
* Provides the file name in the following format: CURRENTTIMESTAMP.EXPERIMENTNAME.FILESUFFIX.
* CURRENTTIMESTAMP is provided in the format "yyyy-MM-dd"
* EXPERIMENTNAME is provided with at most 15 characters and replacing whitespace values with underscore
* FILESUFFIX is set to "rawdata_urls.txt"
*/
@Override
public String getFileName() {
return String.format("%s.%s.%s",
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")),
fileNamePrefixFromExperimentName(experiment.getName()), FILE_SUFFIX);
return String.join("_", fileNamePrefix, FILE_SUFFIX);
}

private String fileNamePrefixFromExperimentName(String experimentName) {
Expand Down
Loading

0 comments on commit 5930d3b

Please sign in to comment.