NotificationsSettingsOperation.java 14.1 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.adobe.granite.ui.components.HtmlResponse
 *  com.adobe.granite.xss.XSSAPI
 *  com.day.cq.i18n.I18n
 *  javax.servlet.http.HttpServletRequest
 *  org.apache.commons.lang.StringUtils
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Properties
 *  org.apache.felix.scr.annotations.Property
 *  org.apache.felix.scr.annotations.Service
 *  org.apache.sling.api.SlingHttpServletRequest
 *  org.apache.sling.api.request.RequestParameter
 *  org.apache.sling.api.resource.ModifiableValueMap
 *  org.apache.sling.api.resource.PersistenceException
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.api.resource.ResourceUtil
 *  org.apache.sling.api.resource.ValueMap
 *  org.apache.sling.servlets.post.Modification
 */
package com.adobe.cq.mobile.notifications.impl.operations;

import com.adobe.cq.mobile.platform.MobileResource;
import com.adobe.cq.mobile.platform.MobileResourceLocator;
import com.adobe.cq.mobile.platform.MobileResourceType;
import com.adobe.cq.mobile.platform.impl.operations.MobileAbstractOperation;
import com.adobe.granite.ui.components.HtmlResponse;
import com.adobe.granite.xss.XSSAPI;
import com.day.cq.i18n.I18n;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.request.RequestParameter;
import org.apache.sling.api.resource.ModifiableValueMap;
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.ResourceUtil;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.servlets.post.Modification;

@Component(metatype=0, label="Associate a Remote Push Cloud Service with the Mobile Application.")
@Service
@Properties(value={@Property(name="sling.post.operation", value={"mobileapps:notificationSettings"})})
public class NotificationsSettingsOperation
extends MobileAbstractOperation {
    public static final String OPERATION_NAME = "notificationSettings";
    public static final String PARAM_APP_INSTANCE = "appInstance";
    public static final String PARAM_NOTIFICATION_CONFIG = "notificationConfig";
    public static final String PARAM_NOTIFICATION_CLOUD = "rpsCloudServicePath";
    public static final String CQ_APPS_NOTIFICATION_CONFIG = "cq-apps-notification-config";
    public static final String APP_ROOT = "/content/mobileapps";
    public static final String PLUGIN_RESOURCE = "plugin";
    public static final String PLUGIN_NAME = "name";
    public static final String PLUGIN_SPEC = "spec";
    public static final String PLUGIN_VERSION = "version";
    public static final String PLUGIN_IS_PUSH = "isPush";
    public static final String PLUGIN_TAG_ROOT = "/widget/plugins/";
    public static final String PLUGIN_PGB_TAG_ROOT = "/widget/gap_plugins/";

    @Override
    protected void perform(SlingHttpServletRequest request, HtmlResponse response, List<Modification> changes) {
        MobileResourceLocator locator;
        I18n i18n = new I18n((HttpServletRequest)request);
        RequestParameter appInstanceParam = request.getRequestParameter("appInstance");
        if (appInstanceParam == null) {
            String message = i18n.get("Missing mandatory parameter {0}", null, new Object[]{"appInstance"});
            String title = i18n.get("Error");
            this.generateError(response, message, title);
            return;
        }
        Resource appInstance = request.getResourceResolver().getResource(appInstanceParam.toString());
        if (appInstance == null) {
            String message = i18n.get("Unable to resolve mobile application {0}", null, new Object[]{appInstanceParam.toString()});
            String title = i18n.get("Error");
            this.generateError(response, message, title);
            return;
        }
        MobileResource mobileResource = (MobileResource)appInstance.adaptTo(MobileResource.class);
        if (!mobileResource.isA(MobileResourceType.INSTANCE.getType())) {
            String message = i18n.get("The resource {0} must be a mobile application", null, new Object[]{mobileResource.getPath()});
            String title = i18n.get("Error");
            this.generateError(response, message, title);
            return;
        }
        String configPath = request.getParameter("notificationConfig");
        if (StringUtils.isEmpty((String)configPath)) {
            String message = i18n.get("Missing mandatory parameter {0}", null, new Object[]{"notificationConfig"});
            String title = i18n.get("Error");
            this.generateError(response, message, title);
            return;
        }
        ResourceResolver resolver = appInstance.getResourceResolver();
        if (this.checkForDuplicateConfig(response, i18n, appInstance, configPath, resolver, locator = (MobileResourceLocator)resolver.adaptTo(MobileResourceLocator.class))) {
            return;
        }
        String cloudServicePath = request.getParameter("rpsCloudServicePath");
        if (StringUtils.isEmpty((String)cloudServicePath)) {
            String message = i18n.get("Missing mandatory parameter {0}", null, new Object[]{"rpsCloudServicePath"});
            String title = i18n.get("Error");
            this.generateError(response, message, title);
            return;
        }
        this.updateMobileServicesConfig(appInstance, cloudServicePath, configPath, response);
        this.updatePushPluginInfo(appInstance, configPath, resolver, response, i18n);
        response.setPath(appInstance.getPath());
        response.setLocation(appInstance.getPath());
        response.addLink("cq-apps-notification-config", this.xssAPI.getValidHref(configPath), i18n.get("Open Configuration"));
    }

    private boolean checkForDuplicateConfig(HtmlResponse response, I18n i18n, Resource appInstance, String configPath, ResourceResolver resolver, MobileResourceLocator locator) {
        Resource appRootResource = resolver.resolve("/content/mobileapps");
        Iterable<MobileResource> shells = locator.findResourcesByType(appRootResource, MobileResourceType.INSTANCE.getType());
        for (MobileResource shell : shells) {
            ValueMap instanceVM;
            String notificationConfig;
            if (shell.getPath().equals(appInstance.getPath()) || (instanceVM = shell.getProperties()) == null || !instanceVM.containsKey((Object)"notificationConfig") || !(notificationConfig = (String)instanceVM.get("notificationConfig", String.class)).equals(configPath)) continue;
            String message = i18n.get("Notification configuration '{0}' already used by '{1}'", "Cloud config path and Title of app instance", new Object[]{notificationConfig, shell.getTitle()});
            String title = i18n.get("Error");
            this.generateError(response, message, title);
            this.addLink(response, "cq-apps-response-already-used-push-config", notificationConfig, i18n.get("Rejected Push Cloud Config"));
            return true;
        }
        return false;
    }

    private void updateMobileServicesConfig(Resource appInstance, String cloudServicePath, String configPath, HtmlResponse response) {
        Resource appContent = appInstance.getChild("jcr:content");
        ResourceResolver resolver = appInstance.getResourceResolver();
        String appContentPath = appContent.getPath();
        ModifiableValueMap properties = (ModifiableValueMap)appContent.adaptTo(ModifiableValueMap.class);
        boolean modified = properties.containsKey((Object)"notificationConfig");
        properties.put((Object)"notificationConfig", (Object)configPath);
        modified = modified || properties.containsKey((Object)"rpsCloudServicePath");
        properties.put((Object)"rpsCloudServicePath", (Object)cloudServicePath);
        boolean hasCloudConfig = properties.containsKey((Object)"mobileServiceConfig") || properties.containsKey((Object)"phonegapConfig");
        String[] configs = (String[])properties.get("cq:cloudserviceconfigs", String[].class);
        ArrayList<String> newConfigs = new ArrayList<String>();
        if (configs != null) {
            for (int i = 0; i < configs.length; ++i) {
                ValueMap vm;
                Resource configResource = resolver.resolve(configs[i]);
                if (configResource == null || ResourceUtil.isNonExistingResource((Resource)configResource) || (vm = configResource.getParent().getChild("jcr:content").getValueMap()).get((Object)"pushServiceId") != null) continue;
                newConfigs.add(configs[i]);
            }
        }
        newConfigs.add(configPath);
        String[] props = new String[newConfigs.size()];
        props = newConfigs.toArray(props);
        properties.put((Object)"cq:cloudserviceconfigs", (Object)props);
        String property = appContentPath + "/" + "notificationConfig";
        String clouds = appContentPath + "/" + "cq:cloudserviceconfigs";
        if (modified) {
            response.onModified(property);
        } else {
            response.onCreated(property);
        }
        if (hasCloudConfig) {
            response.onModified(clouds);
        } else {
            response.onCreated(clouds);
        }
    }

    private void updatePushPluginInfo(Resource appInstance, String configPath, ResourceResolver resolver, HtmlResponse response, I18n i18n) {
        Resource configResource = resolver.resolve(configPath);
        if (configResource == null || ResourceUtil.isNonExistingResource((Resource)configResource)) {
            String message = i18n.get("Unable to read {0}", "Internal error indicating the path passed in does not exist.", new Object[]{configPath});
            String title = i18n.get("Error");
            this.generateError(response, message, title);
            return;
        }
        Resource pluginResource = configResource.getParent().getChild("plugin");
        if (pluginResource == null || ResourceUtil.isNonExistingResource((Resource)pluginResource)) {
            String parentPath = configResource.getParent().getPath();
            String message = i18n.get("Unable to read plugin information from child of {0}", "Internal error indicating the plugin info is not where is should be.", new Object[]{parentPath});
            String title = i18n.get("Error");
            this.generateError(response, message, title);
            return;
        }
        ValueMap pluginInfo = pluginResource.getValueMap();
        String pluginName = (String)pluginInfo.get("name", String.class);
        String pluginSpec = (String)pluginInfo.get("spec", String.class);
        String pluginVersion = (String)pluginInfo.get("version", String.class);
        if (StringUtils.isEmpty((String)pluginName) || StringUtils.isEmpty((String)pluginSpec) || StringUtils.isEmpty((String)pluginVersion)) {
            String message = i18n.get("Cloud config must contain a plugin folder with attributes for {0}, {1}, and {2}", "Push plugins must contain these three data fields, and one or more of them are missing.", new Object[]{"name", "spec", "version"});
            String title = i18n.get("Error");
            this.generateError(response, message, title);
            return;
        }
        Resource appContent = appInstance.getChild("jcr:content");
        if (appContent == null) {
            String message = i18n.get("Unable to find the app's content resource under {0}", "Internal error - an app instance should always have a jcr:content node.", new Object[]{appInstance.getPath()});
            String title = i18n.get("Error");
            this.generateError(response, message, title);
            return;
        }
        String pluginPath = appContent.getPath() + "/widget/plugins/" + pluginName;
        String pgbPath = appContent.getPath() + "/widget/gap_plugins/" + pluginName;
        try {
            this.removePushPlugins(resolver, appContent.getPath() + "/widget/plugins/");
            ResourceUtil.getOrCreateResource((ResourceResolver)resolver, (String)pluginPath, (String)"nt:unstructured", (String)"nt:unstructured", (boolean)true);
            ModifiableValueMap pluginAttributes = (ModifiableValueMap)resolver.getResource(pluginPath).adaptTo(ModifiableValueMap.class);
            pluginAttributes.put((Object)"spec", (Object)pluginSpec);
            pluginAttributes.put((Object)"isPush", (Object)true);
            this.removePushPlugins(resolver, appContent.getPath() + "/widget/gap_plugins/");
            ResourceUtil.getOrCreateResource((ResourceResolver)resolver, (String)pgbPath, (String)"nt:unstructured", (String)"nt:unstructured", (boolean)true);
            ModifiableValueMap pgbPluginAttributes = (ModifiableValueMap)resolver.getResource(pgbPath).adaptTo(ModifiableValueMap.class);
            pgbPluginAttributes.put((Object)"version", (Object)pluginVersion);
            pgbPluginAttributes.put((Object)"isPush", (Object)true);
        }
        catch (PersistenceException e) {
            String message = i18n.get("Unable to save plugin information to app config at {0}", "The information could not be saved.  Permissions issues might cause this.", new Object[]{appContent.getPath()});
            String title = i18n.get("Error");
            this.generateError(response, message, title);
            return;
        }
    }

    private void removePushPlugins(ResourceResolver resolver, String pluginParentFolder) throws PersistenceException {
        Resource pushFolder = ResourceUtil.getOrCreateResource((ResourceResolver)resolver, (String)pluginParentFolder, (String)"nt:unstructured", (String)"nt:unstructured", (boolean)true);
        Iterable existingPlugins = pushFolder.getChildren();
        for (Resource plugin : existingPlugins) {
            Boolean isPlugin = (Boolean)plugin.getValueMap().get("isPush", Boolean.class);
            if (isPlugin == null || !isPlugin.booleanValue()) continue;
            resolver.delete(plugin);
        }
    }
}