diff --git a/bundles/af-core/pom.xml b/bundles/af-core/pom.xml
index 54eed7c5b3..172f68d6fb 100644
--- a/bundles/af-core/pom.xml
+++ b/bundles/af-core/pom.xml
@@ -653,6 +653,10 @@
core.wcm.components.core
provided
+
+ com.adobe.aem
+ core-forms-print-components-print-dor-api
+
org.apache.sling
org.apache.sling.testing.caconfig-mock-plugin
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 d5f64f60d9..862f046330 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
@@ -148,4 +148,7 @@ private FormConstants() {
/** Form definition type indicating submission view */
public static final String FORM_DEFINITION_SUBMISSION = "submission";
+
+ /** The channel for print */
+ public static final String CHANNEL_PRINT = "print";
}
diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/ButtonImpl.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/ButtonImpl.java
index 11d84d0fc6..6597f80a1b 100644
--- a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/ButtonImpl.java
+++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/ButtonImpl.java
@@ -109,6 +109,10 @@ public Map getDorProperties() {
if (dorColspan != null) {
customDorProperties.put("dorColspan", dorColspan);
}
+ Map dorContainer = getDorContainer();
+ if (dorContainer != null) {
+ customDorProperties.put(CUSTOM_DOR_CONTAINER_WRAPPER, dorContainer);
+ }
return customDorProperties;
}
diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/FragmentImpl.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/FragmentImpl.java
index 0614fcef10..ccd0e829d2 100644
--- a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/FragmentImpl.java
+++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/FragmentImpl.java
@@ -15,7 +15,9 @@
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
package com.adobe.cq.forms.core.components.internal.models.v1.form;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
import javax.annotation.PostConstruct;
@@ -57,6 +59,7 @@
public class FragmentImpl extends PanelImpl implements Fragment {
public static final String CUSTOM_FRAGMENT_PROPERTY_WRAPPER = "fd:fragment";
+ private static final String PRINT_CHANNEL_PATH = "/" + "print";
@OSGiService
private SlingModelFilter slingModelFilter;
@@ -72,7 +75,9 @@ public class FragmentImpl extends PanelImpl implements Fragment {
@PostConstruct
private void initFragmentModel() {
ResourceResolver resourceResolver = resource.getResourceResolver();
- fragmentContainer = ComponentUtils.getFragmentContainer(resourceResolver, fragmentPath);
+
+ String updatedFragmentPath = this.getFragmentPathBasedOnChannel(fragmentPath);
+ fragmentContainer = ComponentUtils.getFragmentContainer(resourceResolver, updatedFragmentPath);
if (request != null) {
FormClientLibManager formClientLibManager = request.adaptTo(FormClientLibManager.class);
String clientLibRef = getClientLibForFragment();
@@ -82,6 +87,13 @@ private void initFragmentModel() {
}
}
+ private String getFragmentPathBasedOnChannel(String fragmentPath) {
+ if (FormConstants.CHANNEL_PRINT.equals(this.channel)) {
+ return fragmentPath + PRINT_CHANNEL_PATH;
+ }
+ return fragmentPath;
+ }
+
@JsonView(Views.Author.class)
public String getFragmentPath() {
return fragmentPath;
diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/PanelImpl.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/PanelImpl.java
index b066e38587..4ae32726a3 100644
--- a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/PanelImpl.java
+++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/PanelImpl.java
@@ -145,6 +145,10 @@ public Map getDorProperties() {
if (dorLayoutType != null) {
customDorProperties.put(DOR_LAYOUT_TYPE, dorLayoutType);
}
+ Map dorContainer = getDorContainer();
+ if (dorContainer != null) {
+ customDorProperties.put(CUSTOM_DOR_CONTAINER_WRAPPER, dorContainer);
+ }
return customDorProperties;
}
diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/FormComponent.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/FormComponent.java
index 8416d4ca8c..ee4446c73b 100644
--- a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/FormComponent.java
+++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/FormComponent.java
@@ -76,6 +76,17 @@ default Map getDorProperties() {
return Collections.emptyMap();
}
+ /**
+ * DOR container
+ *
+ * @since com.adobe.cq.forms.core.components.models.form 2.1.0
+ */
+ @JsonView(Views.DoR.class)
+ @JsonInclude(JsonInclude.Include.NON_EMPTY)
+ default Map getDorContainer() {
+ return Collections.emptyMap();
+ }
+
/**
* Returns getPath of the form field
*
diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/util/AbstractComponentImpl.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/util/AbstractComponentImpl.java
index 03f1f20cca..15f4cbb147 100644
--- a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/util/AbstractComponentImpl.java
+++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/util/AbstractComponentImpl.java
@@ -23,10 +23,7 @@
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
-import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy;
-import org.apache.sling.models.annotations.injectorspecific.ScriptVariable;
-import org.apache.sling.models.annotations.injectorspecific.Self;
-import org.apache.sling.models.annotations.injectorspecific.SlingObject;
+import org.apache.sling.models.annotations.injectorspecific.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.osgi.annotation.versioning.ConsumerType;
@@ -43,6 +40,7 @@
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
import com.day.cq.wcm.api.components.ComponentContext;
+import com.fasterxml.jackson.annotation.JsonIgnore;
// this class is copied from WCM, since for forms adapting via slingRequest is optional
@@ -85,6 +83,11 @@ public abstract class AbstractComponentImpl implements Component {
@Nullable
private Page currentPage;
+ @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL, name = "fd:channel")
+ @Nullable
+ @JsonIgnore
+ protected String channel;
+
/**
* The ID for this component.
*/
diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/util/AbstractContainerImpl.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/util/AbstractContainerImpl.java
index 5192fb126b..d5f063d43f 100644
--- a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/util/AbstractContainerImpl.java
+++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/util/AbstractContainerImpl.java
@@ -15,13 +15,7 @@
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
package com.adobe.cq.forms.core.components.util;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import javax.annotation.Nonnull;
import javax.annotation.PostConstruct;
@@ -29,6 +23,10 @@
import org.apache.commons.lang3.ArrayUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceUtil;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.api.wrappers.ValueMapDecorator;
+import org.apache.sling.api.wrappers.ValueMapUtil;
import org.apache.sling.models.annotations.injectorspecific.OSGiService;
import org.apache.sling.models.annotations.injectorspecific.SlingObject;
import org.apache.sling.models.factory.ModelFactory;
@@ -39,9 +37,11 @@
import com.adobe.cq.export.json.ComponentExporter;
import com.adobe.cq.export.json.SlingModelFilter;
+import com.adobe.cq.forms.core.components.internal.form.FormConstants;
import com.adobe.cq.forms.core.components.models.form.Container;
import com.adobe.cq.forms.core.components.models.form.ContainerConstraint;
import com.adobe.cq.forms.core.components.models.form.FormComponent;
+import com.adobe.granite.ui.components.ds.ValueMapResource;
import com.day.cq.wcm.foundation.model.export.AllowedComponentsExporter;
import com.day.cq.wcm.foundation.model.responsivegrid.ResponsiveGrid;
import com.fasterxml.jackson.annotation.JsonInclude;
@@ -143,6 +143,13 @@ protected Map getChildrenModels(@Nullable SlingHttpServletRequest
Map models = new LinkedHashMap<>();
for (Resource child : filteredChildrenResources) {
T model = null;
+ if (FormConstants.CHANNEL_PRINT.equals(this.channel)) {
+ // Create a ValueMap with additional properties
+ ValueMap additionalProperties = new ValueMapDecorator(new HashMap<>());
+ additionalProperties.put("fd:channel", this.channel);
+ ValueMap properties = ValueMapUtil.merge(ResourceUtil.getValueMap(child), additionalProperties);
+ child = new ValueMapResource(child.getResourceResolver(), child.getPath(), child.getResourceType(), properties);
+ }
if (request != null) {
// todo: if possible set i18n form parent to child here, this would optimize the first form rendering
model = modelFactory.getModelFromWrappedRequest(request, child, modelClass);
diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/util/AbstractFormComponentImpl.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/util/AbstractFormComponentImpl.java
index bf2ceebb9e..78898add40 100644
--- a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/util/AbstractFormComponentImpl.java
+++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/util/AbstractFormComponentImpl.java
@@ -17,7 +17,18 @@
import java.io.IOException;
import java.math.BigDecimal;
-import java.util.*;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@@ -44,11 +55,13 @@
import com.adobe.aemds.guide.utils.GuideUtils;
import com.adobe.cq.forms.core.components.datalayer.FormComponentData;
import com.adobe.cq.forms.core.components.internal.datalayer.ComponentDataImpl;
+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.BaseConstraint;
import com.adobe.cq.forms.core.components.models.form.FieldType;
import com.adobe.cq.forms.core.components.models.form.FormComponent;
import com.adobe.cq.forms.core.components.models.form.Label;
+import com.adobe.cq.forms.core.components.models.form.print.dorapi.DorContainer;
import com.adobe.cq.wcm.core.components.models.Component;
import com.adobe.cq.wcm.core.components.util.ComponentUtils;
import com.day.cq.i18n.I18n;
@@ -58,6 +71,7 @@
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -258,6 +272,7 @@ protected boolean getEditMode() {
}
public static final String CUSTOM_DOR_PROPERTY_WRAPPER = "fd:dor";
+ public static final String CUSTOM_DOR_CONTAINER_WRAPPER = "dorContainer";
// used for DOR and SPA editor to work
public static final String CUSTOM_JCR_PATH_PROPERTY_WRAPPER = "fd:path";
@@ -544,6 +559,10 @@ public Map getDorProperties() {
if (dorBindRef != null) {
customDorProperties.put("dorBindRef", dorBindRef);
}
+ Map dorContainer = getDorContainer();
+ if (dorContainer != null) {
+ customDorProperties.put(CUSTOM_DOR_CONTAINER_WRAPPER, dorContainer);
+ }
return customDorProperties;
}
@@ -567,4 +586,26 @@ private List getDisabledXFAScripts() {
}
return new ArrayList<>(disabledScripts);
}
+
+ /**
+ * Returns the dor container properties.
+ *
+ * @return Map of dor container properties if `fd:dorContainer` node is present otherwise returns null
+ */
+ @JsonIgnore
+ @Override
+ public Map getDorContainer() {
+ if (FormConstants.CHANNEL_PRINT.equals(this.channel) && resource != null) {
+ Resource dorContainerResource = resource.getChild("fd:dorContainer");
+ if (dorContainerResource != null) {
+ DorContainer dorContainer = dorContainerResource.adaptTo(DorContainer.class);
+ ObjectMapper objectMapper = new ObjectMapper();
+ if (dorContainer != null) {
+ return objectMapper.convertValue(dorContainer, new TypeReference
+
+ com.adobe.aem
+ core-forms-print-components-print-dor-api
+ ${core.print.api.version}
+
org.apache.commons
commons-text
diff --git a/ui.frontend/package-lock.json b/ui.frontend/package-lock.json
index a20359e29e..d7e6d6c711 100644
--- a/ui.frontend/package-lock.json
+++ b/ui.frontend/package-lock.json
@@ -18348,4 +18348,4 @@
"dev": true
}
}
-}
+}
\ No newline at end of file