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

com.adobe.cq.testing.client.TemplateEditorManagerClient Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2021 Adobe Systems Incorporated
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.adobe.cq.testing.client;

import com.adobe.cq.testing.util.CSRFUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.sling.testing.clients.ClientException;
import org.apache.sling.testing.clients.SlingClientConfig;
import org.apache.sling.testing.clients.SlingHttpResponse;
import org.apache.sling.testing.clients.util.FormEntityBuilder;
import org.apache.sling.testing.clients.util.JsonUtils;

import java.io.IOException;
import java.net.URI;

import static org.apache.sling.testing.Constants.CHARSET_UTF8;
import static org.apache.sling.testing.Constants.PARAMETER_CHARSET;


/**
 * Client to create and update the page template.
 * To create a default template use {@link #createDefaultTemplate(String configPath, String title, String Description)}
 * To create a template with give type use {@link #createTemplate(String configPath, String templateType, String title, String Description)}
 * To create Default Container on top level of a template use {@link #createTopLevelDefaultContainer(String templatePath, String name)}
 * To create a Default container in a template use {@link #createDefaultContainer(String templatePath, String location, String name)}
 */
public final class TemplateEditorManagerClient extends CQClient {

    private static final String TEMPLATE_CREATE_ENDPOINT = "/libs/wcm/core/content/sites/createtemplatewizard/_jcr_content";
    private static final String PATH_PATTERN = "
Path
"; private static final String DD_START_PATTERN = "
"; private static final String DD_END_PATTERN = "
"; private static final String PARAM_HIDDEN = "./hidden"; private static final String PARAM_STATUS = "./status"; private static final String PARAM_TEMPLATE_TYPE = "templateType"; private static final String PARAM_COPY_FROM = "./@CopyFrom"; private static final String PARAM_RESOURCE_TYPE = "./sling:resourceType"; private static final String PARAM_PARENT_RESOURCE_TYPE = "parentResourceType"; private static final String PARAM_NAME_HINT = ":nameHint"; private static final String PARAM_ORDER = ":order"; private static final String PARAM_LOCK = "lock"; private static final String PARAM_JCR_PRIMARY_TYPE = "./jcr:primaryType"; private static final String PARAM_POLICY = "./cq:policy"; private static final String DEFAULT_TEMPLATE_TYPE = "/libs/settings/wcm/template-types/html5page"; private static final String POLICIES_RELATIVE_PATH = "%s/settings/wcm/policies"; private static final String DEFAULT_CONTAINER_RESOURCE_TYPE = "wcm/foundation/components/responsivegrid"; private static final String PROP_JCR_TITLE = "./jcr:title"; private static final String PARAM_DESCRIPTION = "description"; private static final String PARAM_PARENT_PATH = "_parentPath_"; public TemplateEditorManagerClient(final CloseableHttpClient http, final SlingClientConfig config) throws ClientException { super(http, config); } public TemplateEditorManagerClient(final URI serverUrl, final String user, final String password) throws ClientException { super(serverUrl, user, password); } /** * Creates a default page template of type HTML5 * @param configPath path of config to be used to create a page template * @param title title of the template * @param description description of the template * @return created template path * @throws ClientException if the request fails * @throws IOException if json parsing fails */ public String createDefaultTemplate(final String configPath, final String title, final String description) throws ClientException,IOException { return createTemplate(configPath, DEFAULT_TEMPLATE_TYPE, title, description); } /** * Creates a page template with given template type * @param configPath path of config to be used to create a page template * @param templateType type of the template * @param title title of the template * @param description description of the template * @return created template path * @throws ClientException if the request fails * @throws IOException if json parsing fails */ public String createTemplate(final String configPath, final String templateType, final String title, final String description) throws ClientException, IOException { FormEntityBuilder formEntry = FormEntityBuilder.create() .addParameter(PARAMETER_CHARSET, CHARSET_UTF8) .addParameter(CSRFUtils.PARAM_CSRF_TOKEN, CSRFUtils.createCSRFToken(this)) .addParameter(PROP_JCR_TITLE, title) .addParameter(PARAM_DESCRIPTION, description) .addParameter(PARAM_HIDDEN, "true") .addParameter(PARAM_STATUS, "draft") .addParameter(PARAM_PARENT_PATH, configPath) .addParameter(PARAM_TEMPLATE_TYPE, templateType) .addParameter(PARAM_TEMPLATE_TYPE + "@Delete", ""); String content = doPost(TEMPLATE_CREATE_ENDPOINT, formEntry.build(), HttpStatus.SC_CREATED).getContent(); return extractPath(content); } /** * Creates default layout container (responsivegrid) on the provided location of the provided template * * @param templatePath: path of the template the layout container should be created, i.e. /conf/myConfig/settings/wcm/templates/myTemplate * @param location: the location the layout container should be created, i.e. /structure/jcr:content/root/ * @param nameHint: name hint for the layout container or null to create one * @return path of the created layout container * @throws ClientException if the request fails */ public String createDefaultContainer(String templatePath, String location, String nameHint) throws ClientException { if (nameHint == null) nameHint = "responsivegrid"; FormEntityBuilder formEntry = FormEntityBuilder.create() .addParameter(PARAM_COPY_FROM, "/libs/" + DEFAULT_CONTAINER_RESOURCE_TYPE + "/cq:template") .addParameter(PARAMETER_CHARSET, CHARSET_UTF8) .addParameter(PARAM_RESOURCE_TYPE, DEFAULT_CONTAINER_RESOURCE_TYPE) .addParameter(PARAM_PARENT_RESOURCE_TYPE, DEFAULT_CONTAINER_RESOURCE_TYPE) .addParameter(PARAM_ORDER, "last") .addParameter(PARAM_NAME_HINT, nameHint); location = StringUtils.prependIfMissing(location, "/"); String parentPath = templatePath + StringUtils.appendIfMissing(location, "/"); SlingHttpResponse exec = doPost(parentPath, formEntry.build(), HttpStatus.SC_CREATED); return exec.getSlingPath(); } /** * Creates a default layout container (responsivegrid) on structure top level of the provided template * * @param templatePath: path of the template the layout container should be created, i.e. /conf/myConfig/settings/wcm/templates/myTemplate * @param nameHint: name hint for the layout container or null to create one * @return path of the created layout container * @throws ClientException if the request fails */ public String createTopLevelDefaultContainer(String templatePath, String nameHint) throws ClientException { return createDefaultContainer(templatePath, "/structure/jcr:content/root/", nameHint); } /** * Enables a existing template * @param templatePath path of the template to be enabled * @throws ClientException if the request fails */ public void enable(final String templatePath) throws ClientException { setPageProperty(templatePath, PARAM_STATUS, "enabled", HttpStatus.SC_OK); } /** * Disables an existing template * @param templatePath path of the template to be disabled * @throws ClientException if the request fails */ public void disable(final String templatePath) throws ClientException { setPageProperty(templatePath, PARAM_STATUS, "disabled", HttpStatus.SC_OK); } /** * Update the policy of an existing CQConfig with the provides policy * @param configPath path of the config which needs to be updated * @param jsonString policy to be updated in json format * @return updated config path * @throws ClientException if the request fails */ public String importPolicy(final String configPath, final String jsonString) throws ClientException { return importJson( String.format(POLICIES_RELATIVE_PATH, configPath), JsonUtils.getJsonNodeFromString(jsonString), HttpStatus.SC_CREATED ).getSlingPath(); } /** * Unlock a component in the structure tree of a template * * @param componentPath: path of the component to be unlocked * @throws ClientException if the request fails */ public void unlockStructureComponent(final String componentPath) throws ClientException { setStructureComponentLock(componentPath, false); } /** * Lock / unlock a component in the structure tree of a template * * @param componentPath: path of the component to be locked / unlocked * @param isLocked: true to lock the component, false to unlock the component * @throws ClientException if the request fails */ public void setStructureComponentLock(String componentPath, boolean isLocked) throws ClientException { String resourcePath = "/bin/wcm/template/sync.html" + componentPath; FormEntityBuilder form = FormEntityBuilder.create() .addParameter(PARAM_LOCK, "" + isLocked); this.doPost(resourcePath, form.build(), HttpStatus.SC_OK, HttpStatus.SC_CREATED).getContent(); } /** * Set the policy mapping for a component. * Note: The componentPath is the path to the component in the template structure tree except for components in a * unlocked layout container, here the component path is the path to the layout container component in the template * structure tree plus the component resource type, i.e. for a foundation text component in unlocked main layout container: * /conf/myConfig/settings/wcm/templates/myTemplate/structure/jcr:content/root/responsivegrid/wcm/foundation/components/text * * @param componentPath: the path of the component for which the policy should be set * @param policyPath: the path of the policy to be set for the component, i.e. wcm/foundation/components/responsivegrid/default * @return path of the created/updated component policy * @throws ClientException if the request fails */ public String setComponentPolicy(String componentPath, String policyPath) throws ClientException { String resourcePath = StringUtils.replaceOnce(componentPath, "structure", "policies"); FormEntityBuilder form = FormEntityBuilder.create() .addParameter(PARAM_JCR_PRIMARY_TYPE, "nt:unstructured") // set primary type for folder node .addParameter(PARAM_RESOURCE_TYPE, getPolicyMappingResourceType(componentPath)) .addParameter(PARAM_POLICY, policyPath); SlingHttpResponse exec = this.doPost(resourcePath, form.build(), HttpStatus.SC_OK, HttpStatus.SC_CREATED); return exec.getSlingPath(); } /** * Get the resource type of the policy mapping node depending if the component is a page component or not (note: page * components use different resource type in policy mapping than all other components) * * @param componentPath: the path of the component for which the policy should be set * @return resource type of the policy mapping */ private String getPolicyMappingResourceType(String componentPath) { return componentPath.endsWith("/jcr:content") ? "wcm/core/components/policies/mappings" : "wcm/core/components/policies/mapping"; } private String extractPath(final String content) { int indexPath = content.indexOf(PATH_PATTERN); assert indexPath > 0; int indexDDStart = content.indexOf(DD_START_PATTERN, indexPath); assert indexDDStart > 0; int indexDDEnd = content.indexOf(DD_END_PATTERN, indexDDStart); assert indexDDEnd > 0; return content.substring(indexDDStart + DD_START_PATTERN.length(), indexDDEnd); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy