You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2022/06/23 07:33:32 UTC
[isis] branch master updated: ISIS-3077: escape Strings for rendering dynamically based on what the output format dictates
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git
The following commit(s) were added to refs/heads/master by this push:
new d9e7457223 ISIS-3077: escape Strings for rendering dynamically based on what the output format dictates
d9e7457223 is described below
commit d9e74572236081541f8659d488d8ad3b009abfd6
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Jun 23 09:33:24 2022 +0200
ISIS-3077: escape Strings for rendering dynamically based on what the
output format dictates
---
.../viewer/common/model/StringForRendering.java | 49 ++++++++++++++++++++++
.../components/scalars/ScalarPanelAbstract2.java | 33 +++++++++------
.../scalars/ScalarPanelTextFieldAbstract.java | 3 +-
.../blobclob/IsisBlobOrClobPanelAbstract.java | 10 +++--
.../ui/components/scalars/bool/BooleanPanel.java | 3 +-
.../scalars/reference/ReferencePanel.java | 5 ++-
.../scalars/string/ScalarTitleBadgePanel.java | 2 +-
.../valuechoices/ValueChoicesSelect2Panel.java | 5 ++-
.../org/apache/isis/viewer/wicket/ui/util/Wkt.java | 18 ++++++++
9 files changed, 105 insertions(+), 23 deletions(-)
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/StringForRendering.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/StringForRendering.java
new file mode 100644
index 0000000000..dac9a1ea1e
--- /dev/null
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/StringForRendering.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.isis.viewer.common.model;
+
+import java.io.Serializable;
+
+@lombok.Value(staticConstructor = "of")
+public class StringForRendering implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Typically to be rendered with a label component, that supports escaping.
+ * <p>
+ * In other words, given {@code text} must not to be interpreted by the browser, that renders it.
+ */
+ public static StringForRendering text(final String text) {
+ return StringForRendering.of(text, false);
+ }
+
+ /**
+ * Typically to be rendered with a markup component, to be rendered as is.
+ * <p>
+ * In other words, given {@code html} must be interpreted by the browser, that renders it.
+ */
+ public static StringForRendering markup(final String html) {
+ return StringForRendering.of(html, true);
+ }
+
+ private String string;
+ private boolean markup;
+
+}
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract2.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract2.java
index ecc7b4c50b..84f7687405 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract2.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract2.java
@@ -29,7 +29,7 @@ import org.apache.wicket.markup.repeater.RepeatingView;
import org.springframework.lang.Nullable;
import org.apache.isis.applib.value.semantics.ValueSemanticsAbstract.PlaceholderLiteral;
-import org.apache.isis.commons.internal.base._Strings;
+import org.apache.isis.viewer.common.model.StringForRendering;
import org.apache.isis.viewer.wicket.model.models.InlinePromptContext;
import org.apache.isis.viewer.wicket.model.models.ScalarModel;
import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarFragmentFactory.CompactFragment;
@@ -125,7 +125,7 @@ extends ScalarPanelAbstract {
if(isUsingTextarea()) {
return PromptFragment.TEXTAREA
.createFragment(id, this, scalarValueId->{
- val textArea = Wkt.textAreaNoTab(scalarValueId, this::obtainOutputFormat);
+ val textArea = Wkt.textAreaNoTab(scalarValueId, this::outputFormatAsString);
val scalarModel = scalarModel();
Wkt.setFormComponentAttributes(textArea,
scalarModel::multilineNumberOfLines,
@@ -137,8 +137,8 @@ extends ScalarPanelAbstract {
return CompactFragment.LABEL
.createFragment(id, this, scalarValueId->
getFormatModifiers().contains(FormatModifier.NO_OUTPUT_ESCAPE)
- ? Wkt.markup(scalarValueId, this::obtainOutputFormat)
- : Wkt.label(scalarValueId, this::obtainOutputFormat));
+ ? Wkt.markup(scalarValueId, this::outputFormatAsString)
+ : Wkt.labelWithDynamicEscaping(scalarValueId, this::obtainOutputFormat));
}
private boolean isUsingTextarea() {
@@ -151,19 +151,28 @@ extends ScalarPanelAbstract {
return !scalarModel().isEmpty();
}
+ /**
+ * @see #obtainOutputFormat()
+ */
+ protected final String outputFormatAsString() {
+ return obtainOutputFormat().getString();
+ }
+
/**
* Output format (usually HTML) as String, for any non editing scenario.
* <p>
* Usually HTML, except for (non-empty) text-areas or badges (that are already modeled in HTML).
*/
- protected String obtainOutputFormat() {
- return _Strings.nonEmpty(
- isUsingTextarea()
- || getFormatModifiers().contains(FormatModifier.BADGE)
- ? scalarModel().proposedValue().getValueAsTitle().getValue()
- : scalarModel().proposedValue().getValueAsHtml().getValue())
- .orElseGet(()->
- PlaceholderLiteral.NULL_REPRESENTATION.asHtml(this::translate));
+ protected StringForRendering obtainOutputFormat() {
+ val proposedValue = scalarModel().proposedValue();
+ if(!proposedValue.isPresent()) {
+ return StringForRendering.markup(PlaceholderLiteral.NULL_REPRESENTATION.asHtml(this::translate));
+ }
+ val useText = isUsingTextarea()
+ || getFormatModifiers().contains(FormatModifier.BADGE);
+ return useText
+ ? StringForRendering.text(proposedValue.getValueAsTitle().getValue())
+ : StringForRendering.markup(proposedValue.getValueAsHtml().getValue());
}
/**
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldAbstract.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldAbstract.java
index e0e23548e7..ab03f754e1 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldAbstract.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldAbstract.java
@@ -28,6 +28,7 @@ import org.apache.wicket.util.convert.IConverter;
import org.apache.isis.commons.internal.assertions._Assert;
import org.apache.isis.core.metamodel.commons.ScalarRepresentation;
import org.apache.isis.core.metamodel.spec.feature.ObjectFeature;
+import org.apache.isis.viewer.common.model.StringForRendering;
import org.apache.isis.viewer.wicket.model.models.ScalarModel;
import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarFragmentFactory.InputFragment;
import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
@@ -129,7 +130,7 @@ extends ScalarPanelFormFieldAbstract<T> {
// -- CONVERSION
@Override
- protected final String obtainOutputFormat() {
+ protected final StringForRendering obtainOutputFormat() {
// conversion does not affect the output format (usually HTML)
return super.obtainOutputFormat();
}
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/blobclob/IsisBlobOrClobPanelAbstract.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/blobclob/IsisBlobOrClobPanelAbstract.java
index 4b4f1338f1..f846b3a78b 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/blobclob/IsisBlobOrClobPanelAbstract.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/blobclob/IsisBlobOrClobPanelAbstract.java
@@ -33,6 +33,7 @@ import org.apache.isis.applib.value.Blob;
import org.apache.isis.applib.value.Clob;
import org.apache.isis.applib.value.NamedWithMimeType;
import org.apache.isis.applib.value.semantics.ValueSemanticsAbstract.PlaceholderLiteral;
+import org.apache.isis.viewer.common.model.StringForRendering;
import org.apache.isis.viewer.wicket.model.models.ScalarModel;
import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarFragmentFactory.CompactFragment;
import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarFragmentFactory.InputFragment;
@@ -75,7 +76,7 @@ extends ScalarPanelFormFieldAbstract<T> {
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
protected FormComponent createFormComponent(final String id, final ScalarModel scalarModel) {
- val initialCaption = obtainOutputFormat();
+ val initialCaption = outputFormatAsString();
val fileUploadField = Wkt.fileUploadField(id, initialCaption, fileUploadModel());
addAcceptFilterTo(fileUploadField);
return fileUploadField;
@@ -84,18 +85,19 @@ extends ScalarPanelFormFieldAbstract<T> {
// -- OUTPUT FORMAT
@Override
- protected String obtainOutputFormat() {
- return getBlobOrClobFromModel()
+ protected StringForRendering obtainOutputFormat() {
+ val caption = getBlobOrClobFromModel()
.map(NamedWithMimeType::getName)
.orElseGet(()->
PlaceholderLiteral.NULL_REPRESENTATION.asText(this::translate));
+ return StringForRendering.text(caption);
}
@Override
protected Component createComponentForOutput(final String id) {
val link = CompactFragment.LINK
.createFragment(id, this, scalarValueId->
- createDownloadLink(scalarValueId, this::obtainOutputFormat));
+ createDownloadLink(scalarValueId, this::outputFormatAsString));
return link;
}
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/bool/BooleanPanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/bool/BooleanPanel.java
index e3765a2708..e47ee3cb79 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/bool/BooleanPanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/bool/BooleanPanel.java
@@ -26,6 +26,7 @@ import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.form.FormComponent;
import org.apache.isis.commons.internal.exceptions._Exceptions;
+import org.apache.isis.viewer.common.model.StringForRendering;
import org.apache.isis.viewer.wicket.model.models.BooleanModel;
import org.apache.isis.viewer.wicket.model.models.ScalarModel;
import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarFragmentFactory.CompactFragment;
@@ -86,7 +87,7 @@ extends ScalarPanelFormFieldAbstract<Boolean> {
}
@Override
- protected String obtainOutputFormat() {
+ protected StringForRendering obtainOutputFormat() {
throw _Exceptions.unexpectedCodeReach(); // not used in createComponentForOutput(...)
}
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
index 28f51aeb99..dd37d98ea8 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
@@ -35,6 +35,7 @@ import org.apache.isis.applib.value.semantics.ValueSemanticsAbstract.Placeholder
import org.apache.isis.core.metamodel.objectmanager.memento.ObjectMemento;
import org.apache.isis.core.metamodel.spec.ManagedObject;
import org.apache.isis.core.metamodel.util.Facets;
+import org.apache.isis.viewer.common.model.StringForRendering;
import org.apache.isis.viewer.common.model.components.ComponentType;
import org.apache.isis.viewer.wicket.model.models.ScalarModel;
import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarFragmentFactory.CompactFragment;
@@ -74,8 +75,8 @@ public class ReferencePanel extends ScalarPanelSelectAbstract {
}
@Override
- protected String obtainOutputFormat() {
- return select2.obtainOutputFormatModel().getObject();
+ protected StringForRendering obtainOutputFormat() {
+ return StringForRendering.text(select2.obtainOutputFormatModel().getObject());
}
@Override
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/string/ScalarTitleBadgePanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/string/ScalarTitleBadgePanel.java
index 225b026b20..edabbb3bbf 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/string/ScalarTitleBadgePanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/string/ScalarTitleBadgePanel.java
@@ -48,7 +48,7 @@ public class ScalarTitleBadgePanel<T> extends ScalarPanelTextFieldWithValueSeman
@Override
protected Component createComponentForOutput(final String id) {
return CompactFragment.BADGE.createFragment(id, this, scalarValueId->
- Wkt.label(scalarValueId, this::obtainOutputFormat));
+ Wkt.label(scalarValueId, this::outputFormatAsString));
}
}
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/valuechoices/ValueChoicesSelect2Panel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/valuechoices/ValueChoicesSelect2Panel.java
index 6ba5656d23..6bd1cf81a0 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/valuechoices/ValueChoicesSelect2Panel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/valuechoices/ValueChoicesSelect2Panel.java
@@ -28,6 +28,7 @@ import org.wicketstuff.select2.ChoiceProvider;
import org.apache.isis.commons.internal.base._Strings;
import org.apache.isis.core.metamodel.objectmanager.memento.ObjectMemento;
import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.viewer.common.model.StringForRendering;
import org.apache.isis.viewer.wicket.model.models.ScalarModel;
import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarFragmentFactory.InputFragment;
import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelSelectAbstract;
@@ -75,8 +76,8 @@ extends ScalarPanelSelectAbstract {
// --
@Override
- protected String obtainOutputFormat() {
- return select2.obtainOutputFormatModel().getObject();
+ protected StringForRendering obtainOutputFormat() {
+ return StringForRendering.text(select2.obtainOutputFormatModel().getObject());
}
// --
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/util/Wkt.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/util/Wkt.java
index 880d7aa3d9..e37c7a2d56 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/util/Wkt.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/util/Wkt.java
@@ -83,7 +83,9 @@ import org.apache.isis.commons.internal.base._Strings;
import org.apache.isis.commons.internal.debug._Probe;
import org.apache.isis.commons.internal.debug._Probe.EntryPoint;
import org.apache.isis.commons.internal.functions._Functions.SerializableFunction;
+import org.apache.isis.commons.internal.functions._Functions.SerializableSupplier;
import org.apache.isis.core.metamodel.interactions.managed.nonscalar.DataTableModel;
+import org.apache.isis.viewer.common.model.StringForRendering;
import org.apache.isis.viewer.wicket.model.hints.IsisActionCompletedEvent;
import org.apache.isis.viewer.wicket.model.hints.IsisEnvelopeEvent;
import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
@@ -676,6 +678,22 @@ public class Wkt {
return new Label(id, labelModel);
}
+ /**
+ * Whether to escape the underlying String for rendering
+ * is dynamically based on the provided {@link StringForRendering}.
+ */
+ public Label labelWithDynamicEscaping(final String id, final SerializableSupplier<StringForRendering> labelModel) {
+ val label = new Label(id, ()->labelModel.get().getString()) {
+ private static final long serialVersionUID = 1L;
+ // we are using this method as a hook to update the ESCAPE flag before rendering
+ @Override public <C> IConverter<C> getConverter(final Class<C> type) {
+ setEscapeModelStrings(!labelModel.get().isMarkup());
+ return super.getConverter(type);
+ }
+ };
+ return label;
+ }
+
public Label labelNoTab(final String id, final IModel<String> labelModel) {
return new Label(id, labelModel) {
private static final long serialVersionUID = 1L;