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

com.adobe.cq.editor.model.asset.mapping.AssetToComponentMap Maven / Gradle / Ivy

/*************************************************************************
 *
 * ADOBE CONFIDENTIAL
 * __________________
 *
 *  Copyright 2016 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 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.cq.editor.model.asset.mapping;

import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.annotation.PostConstruct;
import javax.inject.Inject;

import com.day.cq.i18n.I18n;
import com.day.cq.wcm.api.components.Component;
import com.day.cq.wcm.api.components.ComponentEditConfig;
import com.day.cq.wcm.api.components.ComponentManager;
import com.day.cq.wcm.api.components.DropTarget;
import org.apache.commons.lang.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.request.RequestParameter;
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.commons.json.JSONArray;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.JSONObject;
import org.apache.sling.commons.json.io.JSONWriter;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.Self;

/**
 * Represents the whole configuration of mappings from assets to components
 */
@Model(adaptables = SlingHttpServletRequest.class)
public final class AssetToComponentMap {

    private static final String ASSET_TO_COMPONENT_MAPPING_PATH = "cq:authoring/assetToComponentMapping";
    private static final String POLICY_RESOURCE_TYPE = "wcm/core/components/policy/policy";
    private static final String POLICY_RESOURCE_TYPE_PROPERTY = "policyResourceType";
    private static final String POLICY_DIRECTORY_RELATIVE_PATH = "settings/wcm/policies/";

    @Self
    private SlingHttpServletRequest slingRequest;

    @Inject
    private ResourceResolver resourceResolver;

    private SortedMap componentDropTargets = new TreeMap();

    private List mappings = new ArrayList();

    private Resource componentResource;

    private I18n i18n;

    @PostConstruct
    protected void initModel() {
        Resource designResource = resourceResolver.getResource(slingRequest.getRequestPathInfo().getSuffix());

        if (designResource == null) {
            return;
        }

        ValueMap designProperties = designResource.getValueMap();

        // Multiple values are stored with the key resourceType
        // There is currently the policy resourceType
        // And the resource type of the resource
        RequestParameter[] resourceTypeRP = slingRequest.getRequestParameters("resourceType");

        String resourceType = null;

        if (resourceTypeRP != null) {
            for (RequestParameter parameter : resourceTypeRP) {
                String type = parameter.getString();
                if (!POLICY_RESOURCE_TYPE.equals(type)) {
                    resourceType = type;
                    break;
                }
            }
        }

        // No resource type is provided on the request and the design node contains the policy resource type property
        if (StringUtils.isEmpty(resourceType) && designProperties.containsKey(POLICY_RESOURCE_TYPE_PROPERTY)) {
            resourceType = designProperties.get(POLICY_RESOURCE_TYPE_PROPERTY, String.class);
        }

        if (StringUtils.isEmpty(resourceType)) {
            resourceType = getPolicyComponentPath(designResource.getPath(), designResource.getName());
        }

        componentResource = resourceResolver.getResource(resourceType);

        if (componentResource == null) {
            return;
        }

        i18n = new I18n(slingRequest);

        // Load the existing mapping of assets to components
        Resource assetToComponentMappingResource = designResource.getChild(ASSET_TO_COMPONENT_MAPPING_PATH);

        ComponentManager componentManager = slingRequest.getResourceResolver().adaptTo(ComponentManager.class);
        Collection components = componentManager.getComponents();

        initComponentDropTargets(components);

        if (assetToComponentMappingResource != null) {
            Iterator iterator = assetToComponentMappingResource.listChildren();

            while (iterator.hasNext()) {
                Resource mappingResource = iterator.next();
                // Pass a copy as the internal state of the objects will vary
                mappings.add(new AssetToComponentMapping(mappingResource, getSelectableDropTargets()));
            }
        }
    }

    /**
     * Extracts the component resource type from the policy path
     *
     * Policy path: policyDirectory/componentResourceType/policyName
     *
     * @param path
     * @param resourceName
     * @return
     */
    private String getPolicyComponentPath(String path, String resourceName) {
        if (StringUtils.isNotEmpty(path)) {
            int directoryPosition = path.indexOf(POLICY_DIRECTORY_RELATIVE_PATH);

            if (directoryPosition < 0) {
                return null;
            }

            String componentPath = path.substring(directoryPosition + POLICY_DIRECTORY_RELATIVE_PATH.length());

            return componentPath.replace("/" + resourceName, "");
        }

        return null;
    }

    private List getSelectableDropTargets() {
        List selectableDropTargets = new ArrayList();

        for (ComponentDropTarget componentDropTarget : componentDropTargets.values()) {
            // Independent copy for later edition
            selectableDropTargets.add(new ComponentDropTarget(componentDropTarget.getComponent(), componentDropTarget.getDropTargets()));
        }

        return  selectableDropTargets;
    }

    private void initComponentDropTargets(Collection components) {
        Iterator iterator = components.iterator();
        componentDropTargets = new TreeMap();

        while (iterator.hasNext()) {
            Component component = iterator.next();

            // Only visible components can be associated
            if (".hidden".equals(component.getComponentGroup())) {
                continue;
            }

            ComponentEditConfig editConfig = component.getEditConfig();

            if (editConfig == null) {
                continue;
            }

            Map dropTargets = editConfig.getDropTargets();

            if (dropTargets == null || dropTargets.isEmpty()) {
                continue;
            }

            componentDropTargets.put(component.getPath(), new ComponentDropTarget(component, dropTargets.values()));
        }
    }

    /**
     * Returns the list of all the {@link AssetToComponentMapping}s
     *
     * @return
     */
    public List getMappings() {
        return mappings;
    }

    /**
     * Returns the formatted data gathering the exhaustive list of component drop targets
     *
     * @return
     * @throws JSONException
     */
    public String getComponentDropTargetsData() throws JSONException {
        StringWriter sw = new StringWriter();
        JSONWriter jw = new JSONWriter(sw);

        jw.object();
        JSONObject componentDropTargetsJs = new JSONObject();

        for (Map.Entry componentDropTargetEntry : componentDropTargets.entrySet()) {
            ComponentDropTarget componentDropTarget = componentDropTargetEntry.getValue();
            String resourceType = componentDropTarget.getResourceType();

            JSONObject componentJS = new JSONObject();

            componentJS.put("title", i18n.getVar(componentDropTarget.getTitle()));
            componentJS.put("resourceType", resourceType);
            componentJS.put("group", i18n.getVar(componentDropTarget.getGroup()));

            JSONArray dropTargetsJS = new JSONArray();

            for (DropTarget dropTarget : componentDropTarget.getDropTargets()) {

                JSONObject obj = new JSONObject();
                obj.put("name", dropTarget.getName());


                if (dropTarget.getAccept() != null) {
                    JSONArray acceptsJS = new JSONArray();

                    for (String accept: dropTarget.getAccept()) {
                        acceptsJS.put(accept);
                    }

                    obj.put("accept", acceptsJS);
                }

                if (dropTarget.getAccept() != null) {
                    JSONArray groupsJS = new JSONArray();

                    for (String group : dropTarget.getGroups()) {
                        groupsJS.put(group);
                    }

                    obj.put("groups", groupsJS);
                }

                dropTargetsJS.put(obj);
            }

            componentJS.put("dropTargets", dropTargetsJS);

            componentDropTargetsJs.put(resourceType, componentJS);
        }

        jw.key("componentDropTargets").value(componentDropTargetsJs);
        jw.endObject();

        return sw.toString();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy