diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/FormConstants.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/FormConstants.java index 1ed99e7d1b..3096f7413b 100644 --- a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/FormConstants.java +++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/FormConstants.java @@ -172,4 +172,7 @@ private FormConstants() { /** The resource type for table row v1 */ public static final String RT_FD_FORM_TABLE_ROW_V1 = RT_FD_FORM_PREFIX + "tablerow/v1/tablerow"; + + /** The resource type for Adobe Sign Block v1 */ + public static final String RT_FD_FORM_ADOBE_SIGN_BLOCK_V1 = RT_FD_FORM_PREFIX + "adobesignblock/v1/adobesignblock"; } diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/AdobeSignBlockImpl.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/AdobeSignBlockImpl.java new file mode 100644 index 0000000000..288e6248af --- /dev/null +++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/AdobeSignBlockImpl.java @@ -0,0 +1,122 @@ +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~ Copyright 2026 Adobe + ~ + ~ Licensed 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 com.adobe.cq.forms.core.components.internal.models.v1.form; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.models.annotations.Default; +import org.apache.sling.models.annotations.Exporter; +import org.apache.sling.models.annotations.Model; +import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy; +import org.apache.sling.models.annotations.injectorspecific.ValueMapValue; + +import com.adobe.cq.export.json.ComponentExporter; +import com.adobe.cq.export.json.ExporterConstants; +import com.adobe.cq.forms.core.components.internal.form.FormConstants; +import com.adobe.cq.forms.core.components.internal.form.ReservedProperties; +import com.adobe.cq.forms.core.components.models.form.Base; +import com.adobe.cq.forms.core.components.models.form.FieldType; +import com.adobe.cq.forms.core.components.models.form.Text; +import com.adobe.cq.forms.core.components.util.AbstractBaseImpl; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; + +/** + * Sling Model for the Adobe Sign Block core component. + * + *

+ * Extends {@link AbstractBaseImpl} (same base as all other form field components) so it participates correctly in + * form-model serialisation and test casting. Implements the {@link Text} interface — replicating the rich-text value + * and fieldType behaviour from {@link TextImpl} — while inheriting: + *

+ * + */ +@Model( + adaptables = { SlingHttpServletRequest.class, Resource.class }, + adapters = { Text.class, Base.class, + ComponentExporter.class }, + resourceType = { FormConstants.RT_FD_FORM_ADOBE_SIGN_BLOCK_V1 }) +@Exporter(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME, extensions = ExporterConstants.SLING_MODEL_EXTENSION) +public class AdobeSignBlockImpl extends AbstractBaseImpl implements Text { + + private static final Pattern ADOBE_SIGN_TAG_PATTERN = Pattern.compile("\\{\\{[*]?([^:]*)_es_:"); + + @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL, name = ReservedProperties.PN_TEXT_IS_RICH) + @Default(booleanValues = false) + private boolean textIsRich; + + @Override + public String getValue() { + return translate("value", value); + } + + @Override + public boolean isRichText() { + return textIsRich; + } + + /** + * Excluded from JSON; the rich-text content is surfaced via {@link #getValue()}. + */ + @Override + @JsonIgnore + public String getText() { + return getValue(); + } + + @Override + public String getFieldType() { + return FieldType.ADOBE_SIGN_BLOCK.getValue(); + } + + /** + * Returns the names of Adobe Sign text-tag fields embedded in this block's HTML content + * (e.g. {@code {{Signature1_es_:signer1:signature}}} yields {@code "Signature1"}). + * Returns {@code null} when no text tags are present so the property is omitted from JSON. + */ + @JsonInclude(JsonInclude.Include.NON_NULL) + public String[] getAdobeSignFields() { + String blockValue = getValue(); + if (blockValue != null && !blockValue.isEmpty()) { + List fieldNames = new ArrayList<>(); + Set seen = new HashSet<>(); + Matcher matcher = ADOBE_SIGN_TAG_PATTERN.matcher(blockValue); + while (matcher.find()) { + String fieldName = matcher.group(1); + if (seen.add(fieldName)) { + fieldNames.add(fieldName); + } + } + if (!fieldNames.isEmpty()) { + return fieldNames.toArray(new String[0]); + } + } + return null; + } +} \ No newline at end of file diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/FieldType.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/FieldType.java index afe215afd1..c704c82db1 100644 --- a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/FieldType.java +++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/FieldType.java @@ -30,6 +30,7 @@ public enum FieldType { DROP_DOWN("drop-down"), RADIO_GROUP("radio-group"), PLAIN_TEXT("plain-text"), + ADOBE_SIGN_BLOCK("adobe-sign-block"), CHECKBOX("checkbox"), BUTTON("button"), PANEL("panel"), diff --git a/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/adobesignblock/.content.xml b/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/adobesignblock/.content.xml new file mode 100644 index 0000000000..8dddf859a6 --- /dev/null +++ b/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/adobesignblock/.content.xml @@ -0,0 +1,7 @@ + + diff --git a/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/adobesignblock/_cq_template.xml b/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/adobesignblock/_cq_template.xml new file mode 100644 index 0000000000..0badb91e77 --- /dev/null +++ b/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/adobesignblock/_cq_template.xml @@ -0,0 +1,8 @@ + + diff --git a/it/content/src/main/content/jcr_root/conf/core-components-it/settings/wcm/policies/.content.xml b/it/content/src/main/content/jcr_root/conf/core-components-it/settings/wcm/policies/.content.xml index f8a5146990..894d852ab6 100755 --- a/it/content/src/main/content/jcr_root/conf/core-components-it/settings/wcm/policies/.content.xml +++ b/it/content/src/main/content/jcr_root/conf/core-components-it/settings/wcm/policies/.content.xml @@ -12,7 +12,7 @@ jcr:primaryType="nt:unstructured" jcr:title="Core Components Examples - Root" sling:resourceType="wcm/core/components/policy/policy" - components="[/libs/wcm/foundation/components/responsivegrid,group:Core Components Examples,group:.core-wcm,group:.core-wcm-form,group:Core Components Examples - Adaptive Form,group:Core Components Examples - Forms And Communications Portal]"> + components="[/libs/wcm/foundation/components/responsivegrid,group:Core Components Examples,group:.core-wcm,group:.core-wcm-form,group:Core Components Examples - Adaptive Form,group:Core Components Examples - Forms And Communications Portal,group:Adobe Sign - Adaptive Form]"> + components="[group:Core Components Examples - Adaptive Form,group:Core Components Examples - Forms And Communications Portal,group:Adobe Sign - Adaptive Form]"> diff --git a/it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/adobesignblock/.content.xml b/it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/adobesignblock/.content.xml new file mode 100644 index 0000000000..e8c65dddff --- /dev/null +++ b/it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/adobesignblock/.content.xml @@ -0,0 +1,7 @@ + +