Skip to content
This repository was archived by the owner on May 5, 2021. It is now read-only.

Commit b2019ac

Browse files
lgallgal
authored andcommitted
Merge remote-tracking branch 'remotes/origin/development' into #3136_sormas-to-sormas-bulk
2 parents 20bd619 + 834a0e2 commit b2019ac

22 files changed

Lines changed: 174 additions & 73 deletions

File tree

sormas-api/src/main/java/de/symeda/sormas/api/caze/classification/ClassificationHtmlRenderer.java

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,14 @@
1717
*******************************************************************************/
1818
package de.symeda.sormas.api.caze.classification;
1919

20+
import static de.symeda.sormas.api.utils.HtmlHelper.escapeAndUnescapeBasicTags;
21+
import static de.symeda.sormas.api.utils.HtmlHelper.unescapeBasicTags;
22+
2023
import java.util.Date;
2124
import java.util.List;
2225

2326
import org.apache.commons.lang3.StringUtils;
27+
import org.apache.commons.text.StringEscapeUtils;
2428

2529
import de.symeda.sormas.api.Disease;
2630
import de.symeda.sormas.api.FacadeProvider;
@@ -31,7 +35,6 @@
3135
import de.symeda.sormas.api.utils.DataHelper;
3236
import de.symeda.sormas.api.utils.DateHelper;
3337
import de.symeda.sormas.api.utils.InfoProvider;
34-
import org.apache.commons.text.StringEscapeUtils;
3538

3639
/**
3740
* Provides methods that create HTML Strings to visualize the automatic classification rules.
@@ -131,18 +134,16 @@ public static String createHtmlForDownload(String sormasServerUrl, List<Disease>
131134
" padding: 8px;\r\n" +
132135
"}\r\n" +
133136
".classification-rules .main-criteria.main-criteria-suspect {\r\n" +
134-
" background: rgba(255, 215, 0, 0.6);\r\n" +
135-
" margin-bottom: 16px;\r\n" +
137+
" background: rgba(255, 215, 0, 0.6);\r\n" +
136138
"}\r\n" +
137139
".classification-rules .main-criteria.main-criteria-probable {\r\n" +
138-
" background: rgba(255, 140, 0, 0.6);\r\n" +
139-
" margin-bottom: 16px;\r\n" +
140+
" background: rgba(255, 140, 0, 0.6);\r\n" +
140141
"}\r\n" +
141142
".classification-rules .main-criteria.main-criteria-confirmed {\r\n" +
142143
" background: rgba(255, 0, 0, 0.6);\r\n" +
143144
"}\r\n" +
144145
".classification-rules .main-criteria.main-criteria-not_a_case {\r\n" +
145-
" background: rgba(201, 201, 201, 0.6);\r\n" +
146+
" background: rgba(160, 160, 160, 0.6);\r\n" +
146147
"}\r\n" +
147148
".classification-rules .headline {\r\n" +
148149
" font-weight: bold;\r\n" +
@@ -188,6 +189,7 @@ public static String createHtmlForDownload(String sormasServerUrl, List<Disease>
188189
html.append(createSuspectHtmlString(diseaseCriteria));
189190
html.append(createProbableHtmlString(diseaseCriteria));
190191
html.append(createConfirmedHtmlString(diseaseCriteria));
192+
html.append(createNotACaseHtmlString(diseaseCriteria));
191193
}
192194
}
193195
html.append("</body></html>");
@@ -239,7 +241,7 @@ private static String buildSubCriteriaDiv(
239241
for (ClassificationCriteriaDto subCriteria : ((ClassificationCollectiveCriteria) criteria).getSubCriteria()) {
240242
if (!(subCriteria instanceof ClassificationCollectiveCriteria) || subCriteria instanceof ClassificationCompactCriteria) {
241243
// For non-collective or compact collective criteria, add the description as a list item
242-
subCriteriaSb.append("- " + subCriteria.buildDescription() + "</br>");
244+
subCriteriaSb.append("- " + escapeAndUnescapeBasicTags(subCriteria.buildDescription() + "</br>"));
243245
} else if (subCriteria instanceof ClassificationCollectiveCriteria
244246
&& !(subCriteria instanceof ClassificationAllOfCriteriaDto)
245247
&& !(subCriteria.getClass() == ClassificationXOfCriteriaDto.class)) {
@@ -273,7 +275,7 @@ private static String createSurroundingDiv(ClassificationCriteriaType criteriaTy
273275
+ "<div class='main-criteria main-criteria-"
274276
+ StringEscapeUtils.escapeHtml4(criteriaType.toString())
275277
+ "'>"
276-
+ StringEscapeUtils.escapeHtml4(content)
278+
+ content
277279
+ "</div></div>";
278280
//@formatter:on
279281
}
@@ -294,11 +296,13 @@ private static String createHeadlineDiv(String headline) {
294296
* Creates a div containing an info text.
295297
*/
296298
private static String createInfoDiv() {
297-
return I18nProperties.getString(Strings.classificationInfoText);
299+
return unescapeBasicTags(StringEscapeUtils.escapeHtml4(I18nProperties.getString(Strings.classificationInfoText)));
298300
}
299301

300302
private static String createInfoDiv(int requirementsNumber) {
301-
return String.format(I18nProperties.getString(Strings.classificationInfoNumberText), DataHelper.parseNumberToString(requirementsNumber));
303+
return unescapeBasicTags(
304+
StringEscapeUtils.escapeHtml4(
305+
String.format(I18nProperties.getString(Strings.classificationInfoNumberText), DataHelper.parseNumberToString(requirementsNumber))));
302306
}
303307

304308
/**
@@ -308,7 +312,7 @@ private static String createCriteriaSurroundingDiv(String content) {
308312

309313
//@formatter:off
310314
return "<div class='criteria'>"
311-
+ StringEscapeUtils.escapeHtml4(content)
315+
+ content
312316
+ "</div>";
313317
//@formatter:on
314318
}
@@ -320,16 +324,17 @@ private static String createSubCriteriaSurroundingDiv(String content) {
320324

321325
//@formatter:off
322326
return "<div class='sub-criteria'><div class='sub-criteria-content'>"
323-
+ StringEscapeUtils.escapeHtml4(content)
327+
+ content
324328
+ "</div></div>";
325329
//@formatter:on
326330
}
327331

328332
/**
329333
* Creates the div for an actual criteria containing its description.
334+
* Specific tags are allowed to be contained in i18n strings and are thus unescaped
330335
*/
331336
private static String createCriteriaItemDiv(String text) {
332-
return StringEscapeUtils.escapeHtml4(text) + "<br/>";
337+
return unescapeBasicTags(StringEscapeUtils.escapeHtml4(text) + "<br>");
333338
}
334339

335340
private enum ClassificationCriteriaType {

sormas-api/src/main/java/de/symeda/sormas/api/facility/FacilityDto.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
*******************************************************************************/
1818
package de.symeda.sormas.api.facility;
1919

20+
import java.util.Arrays;
2021
import java.util.Date;
22+
import java.util.List;
2123

2224
import de.symeda.sormas.api.EntityDto;
2325
import de.symeda.sormas.api.region.CommunityReferenceDto;
@@ -32,6 +34,7 @@ public class FacilityDto extends EntityDto {
3234
public static final String I18N_PREFIX = "Facility";
3335
public static final String OTHER_FACILITY_UUID = "SORMAS-CONSTID-OTHERS-FACILITY";
3436
public static final String NONE_FACILITY_UUID = "SORMAS-CONSTID-ISNONE-FACILITY";
37+
public static final List<String> CONSTANT_FACILITY_UUIDS = Arrays.asList(OTHER_FACILITY_UUID, NONE_FACILITY_UUID);
3538
public static final String OTHER_FACILITY = "OTHER_FACILITY";
3639
public static final String NO_FACILITY = "NO_FACILITY";
3740
public static final String NAME = "name";

sormas-api/src/main/java/de/symeda/sormas/api/infrastructure/PointOfEntryDto.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package de.symeda.sormas.api.infrastructure;
22

3+
import java.util.Arrays;
34
import java.util.Date;
5+
import java.util.List;
46

57
import de.symeda.sormas.api.EntityDto;
68
import de.symeda.sormas.api.region.DistrictReferenceDto;
@@ -15,6 +17,8 @@ public class PointOfEntryDto extends EntityDto {
1517
public static final String OTHER_SEAPORT_UUID = "SORMAS-CONSTID-OTHERS-SEAPORTX";
1618
public static final String OTHER_GROUND_CROSSING_UUID = "SORMAS-CONSTIG-OTHERS-GROUNDCR";
1719
public static final String OTHER_POE_UUID = "SORMAS-CONSTID-OTHERS-OTHERPOE";
20+
public static final List<String> CONSTANT_POE_UUIDS =
21+
Arrays.asList(OTHER_AIRPORT_UUID, OTHER_SEAPORT_UUID, OTHER_GROUND_CROSSING_UUID, OTHER_POE_UUID);
1822
public static final String OTHER_AIRPORT = "OTHER_AIRPORT";
1923
public static final String OTHER_SEAPORT = "OTHER_SEAPORT";
2024
public static final String OTHER_GROUND_CROSSING = "OTHER_GROUND_CROSSING";
@@ -173,4 +177,8 @@ public void setExternalID(String externalID) {
173177
public String toString() {
174178
return InfrastructureHelper.buildPointOfEntryString(getUuid(), name);
175179
}
180+
181+
public PointOfEntryReferenceDto toReference() {
182+
return new PointOfEntryReferenceDto(getUuid(), toString());
183+
}
176184
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package de.symeda.sormas.api.utils;
2+
3+
import org.apache.commons.text.StringEscapeUtils;
4+
5+
public class HtmlHelper {
6+
7+
// unescape specific tags (<b>,<i>,<br>,<li>,<ul>) escaped using StringEscapeUtils.escapeHtml4(String)
8+
public static String unescapeBasicTags(String escapedString) {
9+
String res = escapedString;
10+
11+
// <b> Tags
12+
res = res.replaceAll("&lt;b&gt;", "<b>");
13+
res = res.replaceAll("&lt;/b&gt;", "</b>");
14+
// <i> Tags
15+
res = res.replaceAll("&lt;i&gt;", "<i>");
16+
res = res.replaceAll("&lt;/i&gt;", "</i>");
17+
// <ul> Tags
18+
res = res.replaceAll("&lt;ul&gt;", "<ul>");
19+
res = res.replaceAll("&lt;/ul&gt;", "</ul>");
20+
// <li> Tags
21+
res = res.replaceAll("&lt;li&gt;", "<li>");
22+
res = res.replaceAll("&lt;/li&gt;", "</li>");
23+
// <br> Tags
24+
res = res.replaceAll("&lt;br&gt;", "<br>");
25+
res = res.replaceAll("&lt;/br&gt;", "<br>");
26+
res = res.replaceAll("&lt;br/&gt;", "<br>");
27+
28+
return res;
29+
}
30+
31+
// escapes html4 and then unescapes specific tags
32+
public static String escapeAndUnescapeBasicTags(String text) {
33+
return unescapeBasicTags(StringEscapeUtils.escapeHtml4(text));
34+
}
35+
}

sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/SormasToSormasFacadeEjb.java

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,14 @@
6969
import de.symeda.sormas.api.contact.ContactCriteria;
7070
import de.symeda.sormas.api.contact.ContactDto;
7171
import de.symeda.sormas.api.epidata.EpiDataDto;
72+
import de.symeda.sormas.api.facility.FacilityDto;
7273
import de.symeda.sormas.api.facility.FacilityReferenceDto;
7374
import de.symeda.sormas.api.facility.FacilityType;
7475
import de.symeda.sormas.api.i18n.Captions;
7576
import de.symeda.sormas.api.i18n.I18nProperties;
7677
import de.symeda.sormas.api.i18n.Strings;
7778
import de.symeda.sormas.api.i18n.Validations;
79+
import de.symeda.sormas.api.infrastructure.PointOfEntryDto;
7880
import de.symeda.sormas.api.infrastructure.PointOfEntryReferenceDto;
7981
import de.symeda.sormas.api.location.LocationDto;
8082
import de.symeda.sormas.api.person.PersonDto;
@@ -701,26 +703,39 @@ private DataHelper.Pair<InfrastructureData, List<String>> loadLocalInfrastructur
701703
}
702704

703705
if (facility != null) {
704-
String facilityName = facility.getCaption();
705-
FacilityReferenceDto localFacility =
706-
facilityFacade.getByNameAndType(facilityName, localDistrict, localCommunity, facilityType, false).stream().findFirst().orElse(null);
707-
708-
if (localFacility == null) {
709-
unmatchedFields.add(I18nProperties.getCaption(Captions.facility) + ": " + facilityName);
706+
String facilityUuid = facility.getUuid();
707+
if (FacilityDto.CONSTANT_FACILITY_UUIDS.contains(facilityUuid)) {
708+
infrastructureData.facility = facilityFacade.getByUuid(facilityUuid).toReference();
710709
} else {
711-
infrastructureData.facility = localFacility;
710+
String facilityName = facility.getCaption();
711+
FacilityReferenceDto localFacility = facilityFacade.getByNameAndType(facilityName, localDistrict, localCommunity, facilityType, false)
712+
.stream()
713+
.findFirst()
714+
.orElse(null);
715+
716+
if (localFacility == null) {
717+
unmatchedFields.add(I18nProperties.getCaption(Captions.facility) + ": " + facilityName);
718+
} else {
719+
infrastructureData.facility = localFacility;
720+
}
712721
}
713722
}
714723

715724
if (pointOfEntry != null) {
716-
String pointOfEntryName = pointOfEntry.getCaption();
717-
PointOfEntryReferenceDto localPointOfEntry =
718-
pointOfEntryFacade.getByName(pointOfEntryName, localDistrict, false).stream().findFirst().orElse(null);
725+
String pointOfEntryUuid = pointOfEntry.getUuid();
719726

720-
if (localPointOfEntry == null) {
721-
unmatchedFields.add(I18nProperties.getCaption(Captions.pointOfEntry) + ": " + pointOfEntryName);
727+
if (PointOfEntryDto.CONSTANT_POE_UUIDS.contains(pointOfEntryUuid)) {
728+
infrastructureData.pointOfEntry = pointOfEntryFacade.getByUuid(pointOfEntryUuid).toReference();
722729
} else {
723-
infrastructureData.pointOfEntry = localPointOfEntry;
730+
String pointOfEntryName = pointOfEntry.getCaption();
731+
PointOfEntryReferenceDto localPointOfEntry =
732+
pointOfEntryFacade.getByName(pointOfEntryName, localDistrict, false).stream().findFirst().orElse(null);
733+
734+
if (localPointOfEntry == null) {
735+
unmatchedFields.add(I18nProperties.getCaption(Captions.pointOfEntry) + ": " + pointOfEntryName);
736+
} else {
737+
infrastructureData.pointOfEntry = localPointOfEntry;
738+
}
724739
}
725740
}
726741

sormas-ui/src/main/java/de/symeda/sormas/ui/action/ActionEditForm.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import static de.symeda.sormas.ui.utils.LayoutUtil.locs;
2525

2626
import com.vaadin.v7.ui.ComboBox;
27+
import com.vaadin.v7.ui.Field;
2728
import com.vaadin.v7.ui.Label;
2829
import com.vaadin.v7.ui.RichTextArea;
2930
import com.vaadin.v7.ui.TextField;
@@ -161,7 +162,8 @@ private void updateByCreating() {
161162
}
162163

163164
private void updateByActionContext() {
164-
ActionContext actionContext = (ActionContext) getFieldGroup().getField(ActionDto.ACTION_CONTEXT).getValue();
165+
NullableOptionGroup field = (NullableOptionGroup) getFieldGroup().getField(ActionDto.ACTION_CONTEXT);
166+
ActionContext actionContext = (ActionContext) field.getNullableValue();
165167

166168
// context reference depending on action context
167169
// ready for adding new context

sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/campaigndata/CampaignFormBuilder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,8 +309,8 @@ private boolean fieldValueMatchesDependingOnValues(Field<?> dependingOnField, Li
309309
}
310310

311311
if (dependingOnField instanceof NullableOptionGroup) {
312-
String booleanValue = Boolean.TRUE.equals(dependingOnField.getValue()) ? "true" : "false";
313-
String stringValue = Boolean.TRUE.equals(dependingOnField.getValue()) ? "yes" : "no";
312+
String booleanValue = Boolean.TRUE.equals(((NullableOptionGroup) dependingOnField).getNullableValue()) ? "true" : "false";
313+
String stringValue = Boolean.TRUE.equals(((NullableOptionGroup) dependingOnField).getNullableValue()) ? "yes" : "no";
314314

315315
return dependingOnValuesList.stream()
316316
.anyMatch(v -> v.toString().equalsIgnoreCase(booleanValue) || v.toString().equalsIgnoreCase(stringValue));

sormas-ui/src/main/java/de/symeda/sormas/ui/caze/BulkCaseDataForm.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ protected void addFields() {
310310
warningLayout = VaadinUiUtil.createWarningComponent(I18nProperties.getString(Strings.pseudonymizedCasesSelectedWarning));
311311
facilityOrHome.addValueChangeListener(e -> {
312312
FieldHelper.removeItems(facility);
313-
if (TypeOfPlace.FACILITY.equals(facilityOrHome.getValue())) {
313+
if (TypeOfPlace.FACILITY.equals(facilityOrHome.getNullableValue())) {
314314
if (facilityTypeGroup.getValue() == null) {
315315
facilityTypeGroup.setValue(FacilityTypeGroup.MEDICAL_FACILITY);
316316
}

sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,29 +1084,37 @@ public void openClassificationRulesPopup(DiseaseClassificationCriteriaDto diseas
10841084
classificationRulesLayout.setMargin(true);
10851085

10861086
if (diseaseCriteria != null) {
1087-
Label suspectContent = new Label();
1088-
suspectContent.setContentMode(ContentMode.HTML);
1089-
suspectContent.setWidth(100, Unit.PERCENTAGE);
1090-
suspectContent.setValue(ClassificationHtmlRenderer.createSuspectHtmlString(diseaseCriteria));
1091-
classificationRulesLayout.addComponent(suspectContent);
1092-
1093-
Label probableContent = new Label();
1094-
probableContent.setContentMode(ContentMode.HTML);
1095-
probableContent.setWidth(100, Unit.PERCENTAGE);
1096-
probableContent.setValue(ClassificationHtmlRenderer.createProbableHtmlString(diseaseCriteria));
1097-
classificationRulesLayout.addComponent(probableContent);
1098-
1099-
Label confirmedContent = new Label();
1100-
confirmedContent.setContentMode(ContentMode.HTML);
1101-
confirmedContent.setWidth(100, Unit.PERCENTAGE);
1102-
confirmedContent.setValue(ClassificationHtmlRenderer.createConfirmedHtmlString(diseaseCriteria));
1103-
classificationRulesLayout.addComponent(confirmedContent);
1104-
1105-
Label notACaseContent = new Label();
1106-
notACaseContent.setContentMode(ContentMode.HTML);
1107-
notACaseContent.setWidth(100, Unit.PERCENTAGE);
1108-
notACaseContent.setValue(ClassificationHtmlRenderer.createNotACaseHtmlString(diseaseCriteria));
1109-
classificationRulesLayout.addComponent(notACaseContent);
1087+
if (diseaseCriteria.getSuspectCriteria() != null) {
1088+
Label suspectContent = new Label();
1089+
suspectContent.setContentMode(ContentMode.HTML);
1090+
suspectContent.setWidth(100, Unit.PERCENTAGE);
1091+
suspectContent.setValue(ClassificationHtmlRenderer.createSuspectHtmlString(diseaseCriteria));
1092+
classificationRulesLayout.addComponent(suspectContent);
1093+
}
1094+
1095+
if (diseaseCriteria.getProbableCriteria() != null) {
1096+
Label probableContent = new Label();
1097+
probableContent.setContentMode(ContentMode.HTML);
1098+
probableContent.setWidth(100, Unit.PERCENTAGE);
1099+
probableContent.setValue(ClassificationHtmlRenderer.createProbableHtmlString(diseaseCriteria));
1100+
classificationRulesLayout.addComponent(probableContent);
1101+
}
1102+
1103+
if (diseaseCriteria.getConfirmedCriteria() != null) {
1104+
Label confirmedContent = new Label();
1105+
confirmedContent.setContentMode(ContentMode.HTML);
1106+
confirmedContent.setWidth(100, Unit.PERCENTAGE);
1107+
confirmedContent.setValue(ClassificationHtmlRenderer.createConfirmedHtmlString(diseaseCriteria));
1108+
classificationRulesLayout.addComponent(confirmedContent);
1109+
}
1110+
1111+
if (diseaseCriteria.getNotACaseCriteria() != null) {
1112+
Label notACaseContent = new Label();
1113+
notACaseContent.setContentMode(ContentMode.HTML);
1114+
notACaseContent.setWidth(100, Unit.PERCENTAGE);
1115+
notACaseContent.setValue(ClassificationHtmlRenderer.createNotACaseHtmlString(diseaseCriteria));
1116+
classificationRulesLayout.addComponent(notACaseContent);
1117+
}
11101118
}
11111119

11121120
Window popupWindow = VaadinUiUtil.showPopupWindow(classificationRulesLayout);

sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseCreateForm.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ protected void addFields() {
205205
.updateItems(district, regionDto != null ? FacadeProvider.getDistrictFacade().getAllActiveByRegion(regionDto.getUuid()) : null);
206206
});
207207
district.addValueChangeListener(e -> {
208-
if (!TypeOfPlace.HOME.equals(facilityOrHome.getValue())) {
208+
if (!TypeOfPlace.HOME.equals(facilityOrHome.getNullableValue())) {
209209
FieldHelper.removeItems(facility);
210210
}
211211
FieldHelper.removeItems(community);

0 commit comments

Comments
 (0)