
com.adobe.aemds.guide.common.GuideContainer Maven / Gradle / Ivy
/*************************************************************************
*
* ADOBE CONFIDENTIAL
* __________________
*
* Copyright 2014 Adobe Systems Incorporated
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe Systems Incorporated and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Adobe Systems Incorporated and its
* suppliers and may be covered by U.S. and Foreign Patents,
* patents in process, and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
**************************************************************************/
package com.adobe.aemds.guide.common;
import com.adobe.aemds.guide.service.AdaptiveFormConfigurationService;
import com.adobe.aemds.guide.service.GuideException;
import com.adobe.aemds.guide.service.GuideIntegrationService;
import com.adobe.aemds.guide.service.GuideModelTransformer;
import com.adobe.aemds.guide.service.GuideSchemaType;
import com.adobe.aemds.guide.utils.*;
import com.adobe.forms.common.service.FormsCommonConfigurationService;
import com.adobe.forms.common.utils.TempStorageUtils;
import com.day.cq.commons.jcr.JcrConstants;
import com.day.cq.i18n.I18n;
import com.day.cq.wcm.api.WCMMode;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.api.scripting.SlingBindings;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.JSONObject;
import org.apache.sling.commons.json.io.JSONWriter;
import javax.jcr.RepositoryException;
import javax.script.SimpleBindings;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.StringWriter;
import java.util.*;
/**
* GuideContainer encapsulates basic properties of an adaptive form Container. adaptive form
* Container contains the entire adaptive forms related semantics.
* This consists of few basic properties:
*
* - XDP Reference of adaptive form if any
* - Initialization State of adaptive form container
* - Client Library if configured for the adaptive form
*
* @since 6.0
*/
public class GuideContainer extends GuideNode {
// Please Note: This variable would be set only if this bean is initialized from servlet, otherwise it would
// always be taken from SlingBindings(getGuideModelTransformer)
private GuideModelTransformer guideModelTransformer = null;
private String defaultDataXml = null;
//this flag determines if render json should contain json for
// on demand children (lazy loaded components)
// true value indicates not to bring json for such children
// this flag is used in syncXFAProps
private boolean renderCall = false;
public GuideContainer(){
// default constructor
}
public GuideContainer(SlingHttpServletRequest request, Resource resource){
SimpleBindings bindings = new SimpleBindings();
bindings.put("resource",resource);
bindings.put("request",request);
init(bindings);
}
public GuideContainer(Resource resource){
SimpleBindings bindings = new SimpleBindings();
bindings.put("resource",resource);
init(bindings);
}
public String getRedirect() {
String redirectUrl = resourceProps.get("redirect", "");
return GuideUtils.getRedirectUrl(redirectUrl, getPath());
}
/**
* Sets the number of {@link javax.servlet.RequestDispatcher#include(ServletRequest, ServletResponse)}
* calls that can be reached within the given request if the limit set by system is less than a threshold or
* someone has explicitly set sling.max.calls in request attribute
*
* @param request The request to check
* @pad.exclude Exclude from Published API.
*/
public void setMaxCallCounter(SlingHttpServletRequest request){
boolean setSlingMaxCalls = false;
SlingBindings slingBindings = GuideUtils.getSlingBinding(request);
if(slingBindings != null) {
AdaptiveFormConfigurationService adaptiveFormConfigurationService =
slingBindings.getSling().getService(AdaptiveFormConfigurationService.class);
if(adaptiveFormConfigurationService != null) {
setSlingMaxCalls = adaptiveFormConfigurationService.isSlingMaxCallValueSmall();
}
}
// If the system wide value coming from sling main servlet is less than 20K
// and nobody has explicit set an attribute "sling.max.calls" in the request
// the change the value to 20k
if(setSlingMaxCalls && request.getAttribute(GuideConstants.SLING_MAX_CALLS) == null) {
try {
request.setAttribute(GuideConstants.SLING_MAX_CALLS, GuideConstants.AF_SLING_MAX_CALL_COUNTER);
} catch(Exception e){
logger.error("Cannot increase sling max call value", e);
}
}
}
/**
* Returns weather the form is using old responsive layout or not
* @return Boolean true if the form is using old responsive layout
* @pad.exclude Exclude from Published API.
*/
public Boolean isOldResponsiveLayoutUsed() {
Resource rootPanelResource = getResource().getChild(GuideConstants.ROOTPANEL_NODENAME);
return GuideUtils.hasOldResponsiveLayout(rootPanelResource);
}
/**
* Gives the authoring configuration of the adaptive form container
* @return authoring config of adaptive form container
* @pad.exclude Exclude from Published API.
*/
@Override
public Map getAuthoringConfig(){
Map authoringConfig = super.getAuthoringConfig();
authoringConfig.put(GuideConstants.OLD_RESPONSIVE_LAYOUT_USED, isOldResponsiveLayoutUsed());
String themePath = getThemePath();
if(!themePath.isEmpty()) {
authoringConfig.put(GuideConstants.THEME_PATH, themePath);
String themeClientLibPath = getThemeClientLibPath();
if(StringUtils.isNotEmpty(themeClientLibPath)) {
authoringConfig.put(GuideConstants.THEME_CLIENTLIB_PATH, themeClientLibPath);
}
}
String referredSchemaOrXdp = null;
try {
String afVersion = getVersion();
if(StringUtils.isNotBlank(afVersion)){
authoringConfig.put(GuideConstants.FD_VERSION, afVersion);
}
String aftargetVersion = getTargetVersion();
if(StringUtils.isNotBlank(aftargetVersion)){
authoringConfig.put(GuideConstants.FD_TARGET_VERSION, aftargetVersion);
}
// get dd ref and letter ref explicitly
// since this is deprecated, it is not part of getSchema and getSchemaRef API
String ddRef = resourceProps.get(GuideConstants.DD_REF, "");
String letterRef = resourceProps.get(GuideConstants.LETTER_REF, "");
GuideSchemaType schemaType = getSchema();
String schemaRef = getSchemaRef();
// containsKey condition is used for backward compatibility
// for customers upgrading from 6.2 to 6.4
// check for ddRef is for backwar compatibility
if(StringUtils.isNotBlank(ddRef)){
referredSchemaOrXdp = ddRef;
authoringConfig.put(GuideConstants.DD_REF, referredSchemaOrXdp);
}
// check for letterRef is for backwar compatibility
else if(StringUtils.isNotBlank(letterRef)){
referredSchemaOrXdp = letterRef;
authoringConfig.put(GuideConstants.LETTER_REF, referredSchemaOrXdp);
}
else if(GuideSchemaType.XDP.equals(schemaType)){
referredSchemaOrXdp = schemaRef;
authoringConfig.put(GuideConstants.XDP_REF, referredSchemaOrXdp);
}
else if(GuideSchemaType.XSD.equals(schemaType)) {
referredSchemaOrXdp = schemaRef;
authoringConfig.put(GuideConstants.XSD_REF, referredSchemaOrXdp);
}
else if(StringUtils.isBlank(referredSchemaOrXdp) && StringUtils.isNotBlank(schemaRef)) {
referredSchemaOrXdp = schemaRef;
authoringConfig.put(GuideConstants.SCHEMA_REF, referredSchemaOrXdp);
// todo: why only adding json and fdm schema, ideally every schema type should be made available
if(GuideSchemaType.JSON.equals(schemaType)) {
authoringConfig.put(GuideConstants.SCHEMA_TYPE, GuideConstants.JSON_SCHEMA);
} else if (GuideSchemaType.FDM.equals(schemaType)) {
authoringConfig.put(GuideConstants.SCHEMA_TYPE, GuideConstants.FDM);
}
}
String dorType = getDoRType();
authoringConfig.put(GuideConstants.DOR_TYPE, getDoRType());
if (StringUtils.equals(dorType, GuideConstants.DOR_TYPE_GENERATE)) {
authoringConfig.put(GuideConstants.DOR_TEMPLATE_REF, getDorTemplateRef());
}
} catch (Exception e) {
logger.error("AF: Unable to fetch xsdRef or xdpRef"+ e.getMessage(), e);
}
return authoringConfig;
}
/**
* Returns the document of record type configured for the adaptive form
* @return String representing Document of record type
*/
public String getDoRType() {
return resourceProps.get(GuideConstants.DOR_TYPE, GuideConstants.DOR_TYPE_NONE);
}
/**
* Returns the path of the theme configured during authoring.
* @return String representing path of theme. If path not found return empty String.
*/
private String getThemePath () {
return resourceProps.get(GuideConstants.THEME_CLIENTLIB, "");
}
/**
* Returns the path of the clientlib of theme configured during authoring.
* @return String representing path of clientlib of theme. If path not found return empty String.
*/
private String getThemeClientLibPath() {
String themeClientLibRef = "";
String themePath = getThemePath();
if (!themePath.isEmpty()) {
themePath = themePath + "/" + GuideConstants.JCR_CONTENT_NODENAME;
ResourceResolver resourceResolver = getResource().getResourceResolver();
Resource themeResource = resourceResolver.getResource(themePath);
//This check is required for the cases where theme associated with form gets deleted.
if (themeResource == null) {
return "";
}
themeClientLibRef = GuideThemeUtils.getClientLibPath(themeResource);
}
return themeClientLibRef;
}
/**
* Returns the path of the XDP used in the adaptive form
* @return String representing the XDP reference
* @deprecated
*/
public String getXdpRef() {
return resourceProps.get(GuideConstants.XDP_REF, "");
}
public String getLetterRef() {
return resourceProps.get(GuideConstants.LETTER_REF, "");
}
/**
* Returns meta-template reference associated with adaptive form if exists otherwise empty string.
* @return path of meta-template if exists otherwise empty string
*/
public String getMetaTemplateRef() {
return GuideUtils.getMetaTemplateRef(getResource());
}
/**
* Returns the entire path till init.jsp for the autoSave strategy selected in case of forms built over 6.0
* For 6.1, it returns relative path to support overlay of auto save strategies
*/
public String getAutoSaveStrategyFilePath() {
String autoSaveStrategyType = resourceProps.get("autoSaveStrategyType", "");
if(autoSaveStrategyType!= null && !autoSaveStrategyType.isEmpty()){
return autoSaveStrategyType;
}
return null;
}
/**
* Returns the path of the XDP Template used for generating Document of Record. This returns empty String in case
* of XDP based adaptive forms or if no DOR template is associated while creating adaptive forms
* @return Path of the DOR Template in CRXDE
*/
public String getDorTemplateRef() {
try {
Resource guideContainer = getResource();
ResourceResolver resourceResolver = guideContainer.getResourceResolver();
String guideContainerPath = guideContainer.getPath();
String runtimeLocale = slingRequest.getLocale().toString();
return GuideUtils.getDoRTemplateRef(guideContainerPath, runtimeLocale, resourceResolver);
} catch (Exception e) {
logger.error("Error during fetching dorTemplateRef", e);
}
return "";
}
/**
* Returns the last modified time of the adaptive form Container.
* @return last modified time of the adaptive form container
* @throws RepositoryException
* @private
* @pad.exclude Exclude from Published API.
*/
public Calendar getLastModifiedTime() {
// get the jcr:content node of the adaptive forms CQ Page for last modified time
ValueMap properties = getResource().getParent().adaptTo(ValueMap.class);
return properties.get(GuideConstants.CQ_LAST_MODIFIED, Calendar.class);
}
//TODO : Expose the xsd name
/**
* Returns the path of the XSD used in the adaptive form
* @return reference to the XSD configured for the adaptive form
* @deprecated
*/
public String getXsdRef() {
return resourceProps.get("xsdRef", "");
}
/**
* Returns the path of the Schema used in the adaptive form
* @return reference to the Schema configured for the adaptive form. This reference could be XSD, XDP, JSON or an FDM
*/
public String getSchemaRef() {
String schemaRef = resourceProps.get(GuideConstants.XSD_REF, "");;
// check for xsd ref
if (StringUtils.isBlank(schemaRef)) {
// ask the property from the containing page
schemaRef = getPropertyFromContainingPage(GuideConstants.XSD_REF);
}
if(StringUtils.isBlank(schemaRef)) {
schemaRef = resourceProps.get(GuideConstants.XDP_REF, "");
if(StringUtils.isBlank(schemaRef)) {
// ask the property from the containing page
schemaRef = getPropertyFromContainingPage(GuideConstants.XDP_REF);
}
}
if(StringUtils.isBlank(schemaRef)) {
schemaRef = resourceProps.get(GuideConstants.SCHEMA_REF, "");
if(StringUtils.isBlank(schemaRef)) {
// ask the property from the containing page
schemaRef = getPropertyFromContainingPage(GuideConstants.SCHEMA_REF);
}
}
return schemaRef;
}
private String getPropertyFromContainingPage(String property){
// String propVal = null;
return GuideUtils.getInheritedProperty(getResource(), property);
// todo: may have to change this logic based on the placement of schema ref
/*String fmAssetMetaDataPath = GuideUtils.convertGuideContainerPathToFMAssetMetadataPath(getPath());
Resource metaDataResource = getResource().getResourceResolver().getResource(fmAssetMetaDataPath);
if(metaDataResource != null) {
final ValueMap metaDataProps = metaDataResource.getValueMap();
propVal = metaDataProps.get(property, "");
} */
//return propVal;
}
/**
* Returns the type of the schema configured in the adaptive form
* @return String representing schemaType of form it could have any of the following values present in the {@link GuideSchemaType} enum
* @deprecated
*/
public String getSchemaType() {
return getSchema().getValue();
}
/**
* Returns the prefill service configured in the form
* @return
*/
public String getPrefillService() {
String prefillService = resourceProps.get(GuideConstants.PREFILL_SERVICE, "");
if(StringUtils.isBlank(prefillService)){
prefillService = getPropertyFromContainingPage(GuideConstants.PREFILL_SERVICE);
}
return prefillService;
}
/**
* Returns the {@link GuideSchemaType} configured in the adaptive form
*
* @return {@link GuideSchemaType}
*/
public GuideSchemaType getSchema() {
GuideSchemaType type = GuideSchemaType.BASIC;
String schemaType = resourceProps.get(GuideConstants.SCHEMA_TYPE, "");
if (StringUtils.isNotBlank(schemaType)) {
type = GuideSchemaType.getGuideSchemaType(schemaType);
}
else {
// checking for XSD_REF and XDP_REF separately for upgrade customers from 6.2 to future releases
if (StringUtils.isNotBlank(resourceProps.get(GuideConstants.XSD_REF, ""))) {
type = GuideSchemaType.XSD;
} else if (StringUtils.isNotBlank(resourceProps.get(GuideConstants.XDP_REF, ""))) {
type = GuideSchemaType.XDP;
} else {
String schemaTypeFromContainingPage = getPropertyFromContainingPage(GuideConstants.SCHEMA_TYPE);
if(StringUtils.isNotBlank(schemaTypeFromContainingPage)) {
type = GuideSchemaType.getGuideSchemaType(schemaTypeFromContainingPage);
}
}
}
return type;
}
/**
* Returns the path to the CSS file in CRXDE configured in the authoring of adaptive form
* @return String representing the path to the CSS file configured during authoring.
*/
public String getCssFileRef() {
return resourceProps.get("cssFileRef", String.class);
}
/**
* Returns the name of the client lib associated with the
* adaptive form.
* @return String Name of the client lib
*/
public String getClientLibRef() {
return resourceProps.get("clientLibRef", String.class);
}
/**
* Check if adaptive form container has a toolbar
* @return true, if toolbar present false otherwise
* @pad.exclude Exclude from Published API.
*/
public boolean isHasToolbar(){
return getResource().getChild("toolbar") != null;
}
/**
* Returns the adaptive form Path configured. Used particularly for usecase when
* someone wants to embed adaptive forms inside a web page
* @return path of the adaptive form configured
*/
public String getAfPath(){
return resourceProps.get("afPath", String.class);
}
/**
* Returns the tool bar of the adaptive form container
* @return {@link GuideItemsContainer} toolbar of the adaptive form container
* @see GuideItemsContainer
*/
public GuideItemsContainer getToolbar(){
Resource toolbarResource = getResource().getChild("toolbar");
if(toolbarResource != null){
GuideItemsContainer guideItemsContainer = new GuideItemsContainer();
SimpleBindings bindings = new SimpleBindings();
bindings.put("resource",toolbarResource);
bindings.put("request",slingRequest);
guideItemsContainer.init(bindings);
return guideItemsContainer;
}
return null;
}
/**
* Returns the root panel associated with the adaptive form.
* Root Panel is the parent panel which holds other panel's
* @return Reference to the root panel {@link GuidePanel}
* @see GuidePanel
*/
public GuidePanel getRootPanel() {
return GuideUtils.getRootPanel(getResource(), slingRequest);
}
/**
* Returns if the sync of adaptive form is required or not due to any changes done in XDP
* @return boolean indicating if sync required or not
*/
public boolean isGuideSyncRequired() {
boolean hasXDP = !"".equals(getXdpRef());
return hasXDP && resourceProps.containsKey("formModelChanged");
}
private boolean isSignerAuthenticationCorrect(ValueMap signerProperties) {
return !("PHONE".equals(signerProperties.get("securityOption", "")) &&
(StringUtils.isEmpty(signerProperties.get("countryCode", "")) ||
StringUtils.isEmpty(signerProperties.get("phone", ""))));
}
/**
* Returns whether AdobeSign is enabled or not
* @return
*/
public boolean isAdobeSignEnabled() {
return Boolean.valueOf(resourceProps.get(GuideConstants.USE_SIGNED_PDF, "false"));
}
/**
* Returns whether Form filler is first signer or not
* @return
*/
public boolean isFormFillerFirstSigner() {
if (isAdobeSignEnabled()) {
Resource signerInfoResource = getResource().getChild(GuideConstants.SIGNER_INFO_RESOURCE);
ValueMap signerInfoProperties = signerInfoResource.getValueMap();
return Boolean.valueOf(signerInfoProperties.get("firstSignerFormFiller", "false"));
}
return false;
}
/**
* Returns whether signers are configured correctly or not.
* @return
*/
public boolean isSignatureConfiguredCorrectly() {
if (isAdobeSignEnabled()) {
Resource signerInfoResource = getResource().getChild(GuideConstants.SIGNER_INFO_RESOURCE);
ValueMap signerInfoProperties = signerInfoResource.getValueMap();
if (StringUtils.isEmpty(signerInfoProperties.get(GuideConstants.SIGN_CONFIG_PATH, "")) ||
StringUtils.isEmpty(signerInfoProperties.get("workflowType", ""))) {
return false;
}
Iterator signers = signerInfoResource.getChildren().iterator();
if (!signers.hasNext()) {
return false;
}
Resource firstSigner = signers.next();
ValueMap firstSignerProperties = firstSigner.getValueMap();
if (!(isFormFillerFirstSigner() &&
"userProfile".equals(firstSignerProperties.get("emailSource", ""))) &&
StringUtils.isEmpty(firstSignerProperties.get("email", ""))) {
return false;
}
if (!isSignerAuthenticationCorrect(firstSignerProperties)) {
return false;
}
while (signers.hasNext()) {
Resource signer = signers.next();
ValueMap signerProperties = signer.getValueMap();
if (StringUtils.isEmpty(signerProperties.get("email", ""))) {
return false;
}
if (!isSignerAuthenticationCorrect(signerProperties)) {
return false;
}
}
}
return true;
}
/**
* Returns true if meta-template associated with adaptive form is updated.
* @return boolean indicating if meta-template has been updated.
*/
public boolean isMetaTemplateUpdated() {
boolean isUpdated = false;
String metaTemplateRef = getMetaTemplateRef();
Date lmtOfMetaTemplate = new Date();
Date lmtOfPrint = new Date();
if (getResource() != null) {
Resource print = getResource().getChild("view/print");
if (print != null) {
ValueMap map = print.getValueMap();
lmtOfPrint = map.get(JcrConstants.JCR_LASTMODIFIED, lmtOfPrint);
}
} else {
return false;
}
ResourceResolver resourceResolver = getResource().getResourceResolver();
Resource metaTemplateResource = StringUtils.isNotBlank(metaTemplateRef) ? resourceResolver.getResource(metaTemplateRef) : null;
if (metaTemplateResource != null) {
ValueMap map = metaTemplateResource.getValueMap();
lmtOfMetaTemplate = map.get(JcrConstants.JCR_CREATED, Date.class);
Resource jcrContent = metaTemplateResource.getChild(JcrConstants.JCR_CONTENT);
if (jcrContent != null) {
map = jcrContent.getValueMap();
if (map.containsKey(JcrConstants.JCR_LASTMODIFIED)) {
lmtOfMetaTemplate = map.get(JcrConstants.JCR_LASTMODIFIED, Date.class);
}
}
}
if (lmtOfMetaTemplate.after(lmtOfPrint)) {
isUpdated = true;
}
return isUpdated;
}
/**
* @pad.exclude Exclude from Published API.
*/
public boolean isShowAuthoringWarnings() {
String resourceType = GuideUtils.getNormalizedNodeType(getResourceType(), getResourceSuperType());
boolean showWarnings = true;
if (GuideConstants.RT_GUIDE_DOCUMENT_CONTAINER.equals(resourceType) || GuideConstants.RT_WEB_DOCUMENT_CONTAINER.equals(resourceType)) {
showWarnings = false;
}
return showWarnings;
}
/**
* @pad.exclude Exclude from Published API.
*/
public String getStatusBarTitle() {
// In author mode , we need /i18n/wcm/core and not our dictionary
I18n i18n = new I18n(slingRequest.getResourceBundle(slingRequest.getLocale()));
return i18n.get("Adaptive Form Warnings");
}
public String getMobileLayout() {
String returnLayout = "fd/af/layouts/mobile/simple";
String mobileLayout = null;
try {
mobileLayout = (String) getLayoutProperty("mobileLayout");
} catch (PersistenceException e) {
logger.error("Exception while retrieving mobile layout. " + e.getMessage(), e);
}
if (mobileLayout != null && !mobileLayout.isEmpty()) {
returnLayout = mobileLayout;
}
return returnLayout;
}
/**
* @pad.exclude Exclude from Published API.
*/
public Boolean getParseGridLayoutForMenu() {
Boolean parseGridLayoutForMenu = null;
try {
parseGridLayoutForMenu = Boolean.valueOf(String.valueOf(getLayoutProperty("parseGridLayoutForMenu")));
} catch (PersistenceException e) {
logger.error("Exception while retrieving parseGridLayoutForMenu check. " + e.getMessage(), e);
}
if (parseGridLayoutForMenu == null) {
parseGridLayoutForMenu = Boolean.FALSE;
}
return parseGridLayoutForMenu;
}
/**
* Returns the name of the XDP used in adaptive form. Returns null for non XDP based Forms
* @return String representing the name of the XDP used
*/
public String getXDPName() {
String xdpRef = getXdpRef();
if(xdpRef != null && xdpRef.length() > 0) {
return StringUtils.substring(xdpRef, StringUtils.lastIndexOf(xdpRef, "/") + 1);
}
return null;
}
/**
* Use GuideUtils instead of using this.
* @pad.exclude Exclude from Published API.
*/
public boolean isXDPValid() {
return GuideUtils.isXDPValid(getResource());
}
/**
*
* @param guideModelTransformer
* @pad.exclude Exclude from Published API.
*/
public void setGuideModelTransformer(GuideModelTransformer guideModelTransformer){
this.guideModelTransformer = guideModelTransformer;
}
/***
* @pad.exclude Exclude from Published API.
*/
private GuideModelTransformer getGuideModelTransformer(){
SlingBindings bindings = GuideUtils.getSlingBinding(this.getSlingRequest());
// binding would be null, if this function is invoked from Servlet or there is no request
if(bindings == null){
return this.guideModelTransformer;
} else {
return bindings.getSling().getService(GuideModelTransformer.class);
}
}
/**
* Returns the XFA Json Map containing both XFA Form DOM {@link GuideContainer#getXfaJson}
* and XFA Render Context {@link GuideContainer#getXfaRenderContext}
*
* @return Map Map containing XFA Form DOM and XFA Render Context
* @throws GuideException
*/
private Map getXfaJsonMap() throws GuideException{
String xdpRef = getXdpRef();
Map xfaJsonMap = null;
Boolean isValidXdp = ((xdpRef != null && xdpRef.length() > 0) && this.isXDPValid());
if(isValidXdp) {
GuideModelTransformer guideModelTransformer = getGuideModelTransformer();
xfaJsonMap = guideModelTransformer.exportXfaJson(getResource());
}
return xfaJsonMap;
}
/**
* Returns the parameters required for XFA based adaptive forms to render.
*
* @return containing these parameters
* @throws GuideException
*/
public String getXfaRenderContext() throws GuideException{
String xdpRef = getXdpRef(),
renderContext = "";
if(xdpRef != null && xdpRef.length() > 0){
Map xfaJsonMap = getXfaJsonMap();
if (xfaJsonMap != null && xfaJsonMap.containsKey(GuideConstants.XFA_RENDER_CONTEXT)) {
renderContext = xfaJsonMap.get(GuideConstants.XFA_RENDER_CONTEXT);
}
}
return renderContext;
}
/**
* Returns the XDP Template information required to render XDP based adaptive forms
*
* @return String containing the XDP Template Information
* @throws GuideException
*/
public String getXfaJson() throws GuideException{
String xdpRef = getXdpRef(),
xfaJson = "";
if(xdpRef != null && xdpRef.length() > 0){
Map xfaJsonMap = getXfaJsonMap();
if (xfaJsonMap != null && xfaJsonMap.containsKey(GuideConstants.XFA_FORMDOM)) {
xfaJson = xfaJsonMap.get(GuideConstants.XFA_FORMDOM);
}
}
return xfaJson;
}
/**
* Gets the guide current state json based on guideStatePath or guideStatePathRef.
* a) guideStatePathRef is set by draft provider service
* b) If guideStatePathRef or guideStatePath is not set, then the current state json is
* created from "data" attribute set in request or from "dataRef" attribute / parameter set in request
* @param locale locale string
* @return String GuideCurrentStateJson
* @pad.exclude
*/
public String getGuideCurrentStateJson(String locale){
String guideCurrentStateJson = "";
GuideModelTransformer guideModelTransformer = getGuideModelTransformer();
// First look for guideStatePath in request, if not found then look for guideStatePathRef
// Export the guideJson based on these params
String guideStatePath = (String) slingRequest.getAttribute("guideStatePath");
if (guideStatePath == null || guideStatePath.isEmpty()) {
guideStatePath = slingRequest.getParameter("guideStatePath");
}
String guideStatePathRef = (String) slingRequest.getAttribute("guideStatePathRef");
if (guideStatePathRef == null || guideStatePathRef.isEmpty()) {
guideStatePathRef = slingRequest.getParameter("guideStatePathRef");
}
if (guideStatePath != null && !guideStatePath.isEmpty()) {
guideCurrentStateJson = guideModelTransformer.exportGuideState(guideStatePath);
} else if (guideStatePathRef != null && !guideStatePathRef.isEmpty()) {
guideCurrentStateJson = guideModelTransformer.exportGuideStateFromStore(guideStatePathRef);
}
if(guideCurrentStateJson.length() == 0) {
boolean dataPresent = false;
JSONCreationOptions options = new JSONCreationOptions();
options.setI18n(i18n).setFormContainerPath(getFormContainerPath()).setLocale(new Locale(locale));
String dataRef = (String) slingRequest.getAttribute("dataRef");
if (dataRef == null || dataRef.isEmpty()) {
dataRef = slingRequest.getParameter("dataRef");
}
if (dataRef != null && !dataRef.isEmpty()) {
options.setDataRef(dataRef);
dataPresent = true;
}
String data = (String) slingRequest.getAttribute("data");
//added support to read data from parameter to support AJAX based calls to
//get the container (for ABTest)
if(data == null || data.isEmpty()) {
data = slingRequest.getParameter("data");
}
if (data != null && !data.isEmpty()) {
options.setDataRef(null).setData(data);
dataPresent = true;
}
String prefillService = getPrefillService();
if(prefillService != null) {
dataPresent = true;
}
Map prefillServiceParamMap = (Map) slingRequest.getAttribute(GuideConstants.GUIDE_PREFILL_SERVICE_PARAMS);
if(prefillServiceParamMap != null){
options.setPrefillServiceParams(prefillServiceParamMap);
}
boolean useTestDataPrefillService = true;
if(slingRequest != null){
options.setRequest(slingRequest);
// ask the forms common configuration service to check if we need to use test data prefill service to fetch test data
// by default, we always use the test data prefill service in authoring preview when there is no dataRef set
if(slingRequest != null) {
SlingBindings bindings = GuideUtils.getSlingBinding(slingRequest);
// binding would be null, if this function is invoked from Servlet or there is no request
if (bindings != null) {
FormsCommonConfigurationService formsCommonConfigurationService = bindings.getSling().getService(FormsCommonConfigurationService.class);
useTestDataPrefillService = formsCommonConfigurationService.useTestDataPrefillService();
}
}
}
// we support test data only in case of wcm mode preview
if (dataPresent || (slingRequest != null && WCMMode.fromRequest(slingRequest).equals(WCMMode.PREVIEW) && useTestDataPrefillService)) {
guideCurrentStateJson = guideModelTransformer.getDataJson(getResource(), options);
}
}
return guideCurrentStateJson;
}
/**
* Returns the formContainerPath if set in request attribute and parameter
* @return path of the form container set in the request attribute or parameter
*/
private String getFormContainerPath() {
if (slingRequest == null) {
return null;
}
String formContainerPath = (String) slingRequest.getAttribute("formContainerPath");
if (formContainerPath == null) {
formContainerPath = slingRequest.getParameter("formContainerPath");
}
return formContainerPath;
}
/**
* Returns the merge json of the adaptive form using the data XML passed
* @param locale locale string
* @param dataXml String representing data of adaptive form as XML
* @return String Merge JSON formed after merge of
* @pad.exclude
*/
public String getGuideCurrentStateJson(String locale, String dataXml) {
JSONCreationOptions options = new JSONCreationOptions();
options.setData(dataXml).setI18n(i18n).setFormContainerPath(getFormContainerPath()).setLocale(new Locale(locale));
return guideModelTransformer.getDataJson(getResource(), options);
}
/**
* Returns adaptive form specific data required to render an adaptive form
* @return String containing the specific data
*/
public String getGuideContext(){
return exportInitialGuideContext();
}
/**
* Returns the adaptive form information for rendering an adaptive form on Client
* @return String containing adaptive form Information
*/
public String getGuideJson() {
//TODO: Remove if not used
I18n i18ntemp = i18n;
if(slingRequest != null && getIsEditMode()) {
i18ntemp = null;
}
GuideModelTransformer guideModelTransformer = getGuideModelTransformer();
return guideModelTransformer.exportGuideJson(getResource(), i18ntemp);
}
/**
* @pad.exclude Exclude from Published API.
*/
public String getLayout() {
String layoutpath;
try {
Map layoutproperties;
//To handle a non-default container return the layout for the guide container calling the API.
//(as a fallback, the original code of using a hard-coded path is retained - if caller is not a container)
String containerName = GuideContainerThreadLocal.getGuideContainerName();
if(containerName != null) {
layoutproperties = NodeStructureUtils.getLayoutProperties(slingRequest, getResource(), containerName);
}
else if(GuideUtils.isGuideContainerResource(getResource())) {
layoutproperties = NodeStructureUtils.getLayoutProperties(slingRequest, getResource(), getResource().getName());
}
else {
layoutproperties = NodeStructureUtils.getLayoutProperties(slingRequest, getResource(), NodeStructureUtils.GUIDECONTAINER_NODENAME);
}
layoutpath = (String)layoutproperties.get(NodeStructureUtils.LAYOUT_PATH_PROPERTY);
// Written to support existing templates
if (layoutpath.startsWith("/libs/") || layoutpath.startsWith("/apps/")) {
layoutpath = layoutpath.substring(6);
}
} catch(Exception ex){
logger.error("Unable to get layout of guide container" + ex.getMessage());
throw new GuideException(ex.getMessage(), ex);
}
return layoutpath;
}
/**
* @pad.exclude Exclude from Published API.
*/
public List getGuideIntegrationServiceScriptPaths() {
SlingBindings bindings = (SlingBindings) slingRequest.getAttribute(SlingBindings.class.getName());
GuideIntegrationService guideIntegrationService = bindings.getSling().getService(GuideIntegrationService.class);
return guideIntegrationService.getScriptPaths();
}
/**
* @pad.exclude Exclude from Published API.
*/
private String createGuideInitializationState(String dataXml, String locale){
StringWriter jsonStringWriter = new StringWriter();
JSONWriter jsonWriter = new JSONWriter(jsonStringWriter);
// Check if guide present in cache
GuideModelTransformer guideTransformer = getGuideModelTransformer();
// When creating guide initialization state, we sync XFA props in server and cache it
// On client, we don't do sync xfa props now
Map jsonMap = guideTransformer.syncXfaProps(this, locale);
// Cache guidejson ane xfajson wrt to guideContainer path
// if json not present in cache create it, else always use from the cache for given guide
try {
jsonWriter.object();
jsonWriter.key("guidejson").value(jsonMap.get("guidejson"));
jsonWriter.key("guidecontext").value(getGuideContext());
String mergedJson = null;
// in case of server side validation/test cases, there is no sling request set
if (slingRequest == null || !getIsEditMode()) {
if (dataXml != null) {
mergedJson = getGuideCurrentStateJson(locale, dataXml);
} else {
mergedJson = getGuideCurrentStateJson(locale);
}
}
jsonWriter.key("guidemergedjson").value(mergedJson);
jsonWriter.key("xfajson").value(jsonMap.get("xfajson"));
jsonWriter.key("xfarendercontext").value(getXfaRenderContext());
jsonWriter.endObject();
} catch(JSONException ex){
logger.error("Error in getting guide initialization state" + ex.getMessage());
throw new GuideException(ex.getMessage(), ex);
}
return jsonStringWriter.toString();
}
/**
* Returns the initialization state of the adaptive form which includes guideJson, guideContext, guideMergeJson, xfaJson, xfaRenderContext.
* @return String representing the JSON of the guide initialization state
* @pad.exclude
*/
public String getGuideInitializationState() {
String locale = GuideUtils.getGuideRuntimeLocale(slingRequest, getResource());
return createGuideInitializationState(null,locale);
}
/**
* Returns the initialization state of the adaptive from the data XML and locale passed.
* This initialization state includes guideJson, guideContext, guideMergeJson, xfaJson, xfaRenderContext.
* @param dataXml string representing data xml
* @param locale locale string
* @return String representing the guide initialization state
* @pad.exclude
*/
public String getGuideInitializationState(String dataXml, String locale){
return createGuideInitializationState(dataXml, locale);
}
/**
* @pad.exclude Exclude from Published API.
* Set to true if called while rendering to contain skip
* on demand components
* @param isRenderCall true if you do not want JSON of 'on demand' children
*/
public void setRenderCall(boolean isRenderCall) {
this.renderCall = isRenderCall;
}
/**
* Gets the value for render
* @return boolean value indicating if its a render call
*/
public boolean isRenderCall() {
return renderCall;
}
/**
* Populates and returns the JSON Object from Custom Property Map attribute from request
* @param request
* @return json object representing the custom context property set in the request
*/
public JSONObject getCustomContextPropJson(HttpServletRequest request) {
Object attr = request.getAttribute("customContextProperty");
JSONObject customContextPropJson = new JSONObject();
if (attr != null) {
try {
customContextPropJson = new JSONObject(attr.toString());
} catch (JSONException e) {
logger.error("Failed to parse JSON for customContextProperty attribute", e);
}
}
return customContextPropJson;
}
/**
* Returns the path of the page in which the guideContainer is present.
* @return path of the page in which the adaptive form container is present
*/
public String getPagePath() {
String path = "";
Resource parent = getResource();
while((parent = parent.getParent()) != null) {
if (parent.isResourceType("foundation/components/page")
|| parent.isResourceType("wcm/foundation/components/page")) {
path = parent.getPath();
}
}
return path;
}
/**
* Returns a json object containing guide path, guide name, xdpRef and xsdRef.
* xdpRef is not present if the xdp is invalid
* @return String representation of guideContext
* @throws GuideException
*/
private String exportInitialGuideContext() throws GuideException {
JSONObject contextObject = new JSONObject();
try {
String guideName = this.getName(); //TODO: solve guideName issue
ValueMap guideProps = this.getResource().adaptTo(ValueMap.class);
contextObject.put(GuideConstants.GUIDE_PATH, this.getPath());
contextObject.put(GuideConstants.GUIDE_NAME, guideName);
GuideSchemaType schemaType = getSchema();
String schemaRef = getSchemaRef();
boolean isDataModelSet = false;
if (GuideSchemaType.XSD.equals(schemaType)) {
contextObject.put(GuideConstants.XSD_REF, schemaRef);
isDataModelSet = true;
}
// checking for validXDP since FM doesn't remove the property after deleting the xdp
if (GuideSchemaType.XDP.equals(schemaType) && GuideUtils.isXDPValid(this.getResource())) {
contextObject.put(GuideConstants.XDP_REF, schemaRef);
isDataModelSet = true;
}
if (StringUtils.isNotBlank(schemaRef) && !isDataModelSet) {
contextObject.put(GuideConstants.SCHEMA_REF, schemaRef);
}
if (schemaType != null) {
contextObject.put(GuideConstants.SCHEMA_TYPE, schemaType.getValue());
}
SlingHttpServletRequest slingRequest = this.getSlingRequest();
if(slingRequest != null) {
SlingBindings bindings = GuideUtils.getSlingBinding(this.getSlingRequest());
// binding would be null, if this function is invoked from Servlet or there is no request
if(bindings != null){
FormsCommonConfigurationService formsCommonConfigurationService = bindings.getSling().getService(FormsCommonConfigurationService.class);
AdaptiveFormConfigurationService adaptiveFormConfigurationService = bindings.getSling().getService(AdaptiveFormConfigurationService.class);
boolean isAnonymous = slingRequest.getAuthType() == null;
String tempStorageConfig = formsCommonConfigurationService.getTempStorageConfig();
contextObject.put(GuideConstants.DISABLE_PREVIEW, TempStorageUtils.isPreviewDisabled(tempStorageConfig, isAnonymous));
contextObject.put(GuideConstants.MAKE_FILE_NAMES_UNIQUE, adaptiveFormConfigurationService.getMakeFileNamesUnique());
contextObject.put(GuideConstants.SCRIPTING_BEHAVIOR, adaptiveFormConfigurationService.getScriptingCompatibilityMode());
}
}
} catch (Exception e) {
logger.error("Error in getting guideContext", e);
throw new GuideException(e);
}
return contextObject.toString();
}
/**
* Checks if path pointed by metaTemplateRef is valid resource.
* @return false if the resource is null or metaTemplateRef property is null/empty string,
* true otherwise
*/
public boolean isMetaTemplateValid() {
String metaTemplateRef = getMetaTemplateRef();
return GuideUtils.isMetaTemplateValid(getResource().getResourceResolver(), metaTemplateRef);
}
/** Static methods for instantiating GuideContainer **/
/**
* Static method to construct a {@link GuideContainer} model from a resource
* @param resource guideContainer {@link Resource}
* @return {@link GuideContainer} bean
*/
public static GuideContainer from(Resource resource){
return new GuideContainer(resource);
}
/**
* Static method to construct a {@link GuideContainer} model from a {@link Resource} and {@link SlingHttpServletRequest}
* @param resource guideContainer {@link Resource}
* @param request {@link SlingHttpServletRequest}
* @return {@link GuideContainer} bean
*/
public static GuideContainer from(SlingHttpServletRequest request, Resource resource){
return new GuideContainer(request, resource);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy