All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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