UpdateServlet.java 13.6 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.adobe.granite.license.ProductInfo
 *  com.adobe.granite.license.ProductInfoService
 *  com.adobe.granite.xss.XSSAPI
 *  com.day.cq.i18n.I18n
 *  com.day.jcr.vault.fs.api.Filter
 *  com.day.jcr.vault.fs.api.FilterSet
 *  com.day.jcr.vault.fs.api.PathFilterSet
 *  com.day.jcr.vault.fs.api.WorkspaceFilter
 *  com.day.jcr.vault.fs.config.DefaultWorkspaceFilter
 *  com.day.jcr.vault.fs.filter.DefaultPathFilter
 *  com.day.jcr.vault.packaging.JcrPackage
 *  com.day.jcr.vault.packaging.JcrPackageDefinition
 *  com.day.jcr.vault.packaging.JcrPackageManager
 *  com.day.jcr.vault.packaging.PackageId
 *  com.day.jcr.vault.packaging.PackagingService
 *  javax.jcr.AccessDeniedException
 *  javax.jcr.Node
 *  javax.jcr.PathNotFoundException
 *  javax.jcr.Property
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  javax.jcr.Value
 *  javax.servlet.ServletException
 *  javax.servlet.http.HttpServletRequest
 *  javax.servlet.http.HttpServletResponse
 *  org.apache.commons.io.FileUtils
 *  org.apache.commons.io.IOUtils
 *  org.apache.commons.lang3.StringUtils
 *  org.apache.jackrabbit.commons.JcrUtils
 *  org.apache.sling.commons.json.JSONArray
 *  org.apache.sling.commons.json.JSONException
 *  org.apache.sling.commons.json.JSONObject
 *  org.apache.sling.commons.json.io.JSONWriter
 *  org.apache.tika.Tika
 *  org.osgi.framework.BundleContext
 *  org.osgi.framework.Version
 *  org.slf4j.Logger
 */
package com.day.crx.packmgr.impl.servlets;

import com.adobe.granite.license.ProductInfo;
import com.adobe.granite.license.ProductInfoService;
import com.adobe.granite.xss.XSSAPI;
import com.day.cq.i18n.I18n;
import com.day.crx.packmgr.impl.AbstractServlet;
import com.day.crx.packmgr.impl.support.BlobFactory;
import com.day.crx.packmgr.impl.support.BlobFactoryImpl;
import com.day.crx.packmgr.impl.support.HttpMultipartPost;
import com.day.jcr.vault.fs.api.Filter;
import com.day.jcr.vault.fs.api.FilterSet;
import com.day.jcr.vault.fs.api.PathFilterSet;
import com.day.jcr.vault.fs.api.WorkspaceFilter;
import com.day.jcr.vault.fs.config.DefaultWorkspaceFilter;
import com.day.jcr.vault.fs.filter.DefaultPathFilter;
import com.day.jcr.vault.packaging.JcrPackage;
import com.day.jcr.vault.packaging.JcrPackageDefinition;
import com.day.jcr.vault.packaging.JcrPackageManager;
import com.day.jcr.vault.packaging.PackageId;
import com.day.jcr.vault.packaging.PackagingService;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.UUID;
import javax.jcr.AccessDeniedException;
import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Value;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.jackrabbit.commons.JcrUtils;
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.tika.Tika;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Version;
import org.slf4j.Logger;

public class UpdateServlet
extends AbstractServlet {
    private ProductInfoService productInfoService;
    private XSSAPI xssAPI;

    public UpdateServlet(BundleContext bc, ProductInfoService productInfoService, XSSAPI xssAPI) {
        super(bc);
        this.productInfoService = productInfoService;
        this.xssAPI = xssAPI;
    }

    private String getPath(HttpMultipartPost hmp) {
        String path = hmp.getParameter("path");
        if (path == null) {
            path = hmp.getParameter("Path");
        }
        return "".equals(path) ? "/" : path;
    }

    @Override
    protected void doService(HttpServletRequest req, HttpServletResponse res, Session session) throws ServletException, IOException {
        BlobFactoryImpl blobFactory = new BlobFactoryImpl();
        HttpMultipartPost hmp = new HttpMultipartPost(blobFactory, req);
        boolean success = true;
        String msg = I18n.get((HttpServletRequest)req, (String)"Package updated successfully");
        String path = this.getPath(hmp);
        try {
            String desc;
            PackageId id;
            JcrPackageManager packMgr = PackagingService.getPackageManager((Session)session);
            Node packageNode = null;
            try {
                packageNode = path == null ? null : session.getNode(path);
            }
            catch (RepositoryException e) {
                // empty catch block
            }
            JcrPackage pack = packMgr.open(packageNode);
            JcrPackageDefinition def = pack.getDefinition();
            String packageName = hmp.getParameter("packageName");
            String groupName = hmp.getParameter("groupName");
            String version = hmp.getParameter("version");
            if (version == null) {
                version = "";
            }
            if (!((id = def.getId()).getGroup().equals(groupName) && id.getName().equals(packageName) && id.getVersionString().equals(version))) {
                pack = packMgr.rename(pack, groupName, packageName, version);
                path = pack.getNode().getPath();
            }
            if ((desc = hmp.getParameter("description")) != null) {
                def.set("jcr:description", desc, false);
            }
            UpdateServlet.updateFilter(def, hmp.getParameter("filter"));
            UpdateServlet.updateThumbnail(def, hmp.getFileParameter("thumbnail"));
            this.updateScreenshots(req, def, hmp);
            UpdateServlet.write(hmp, "testedWith", def, "testedWith");
            String v = hmp.getParameter("acHandling");
            if (v != null && v.trim().length() > 0 && !"-".equals(v)) {
                def.set("acHandling", v, false);
            }
            UpdateServlet.write(hmp, "fixedBugs", def, "fixedBugs");
            UpdateServlet.writeBool(hmp, "requiresRoot", def, "requiresRoot");
            UpdateServlet.writeBool(hmp, "requiresRestart", def, "requiresRestart");
            UpdateServlet.writeMulti(hmp, "dependencies", def, "dependencies");
            UpdateServlet.writeMulti(hmp, "replaces", def, "replaces");
            UpdateServlet.write(hmp, "providerName", def, "providerName");
            UpdateServlet.write(hmp, "providerUrl", def, "providerUrl");
            UpdateServlet.write(hmp, "providerLink", def, "providerLink");
            this.updateBuiltWith(def);
            def.touch(null, false);
            session.save();
        }
        catch (AccessDeniedException e) {
            success = false;
            msg = I18n.get((HttpServletRequest)req, (String)"You are not allowed to edit this package.");
        }
        catch (Exception e) {
            success = false;
            this.logger.error("Error while updating package: " + path, (Throwable)e);
            msg = I18n.get((HttpServletRequest)req, (String)"Could not modify package. ") + e.getMessage();
        }
        try {
            res.setContentType("text/html; charset=utf-8");
            JSONWriter w = new JSONWriter((Writer)res.getWriter());
            w.object();
            w.key("success").value(success);
            w.key("msg").value((Object)this.xssAPI.encodeForHTML(msg));
            w.key("path").value((Object)this.xssAPI.encodeForHTML(path));
            w.endObject();
        }
        catch (Exception e) {
            this.logger.error("Error while updating package: " + path, (Throwable)e);
            res.sendError(500);
        }
    }

    private static void updateFilter(JcrPackageDefinition def, String filters) throws JSONException {
        if (StringUtils.isBlank((CharSequence)filters)) {
            return;
        }
        DefaultWorkspaceFilter packFilter = new DefaultWorkspaceFilter();
        JSONArray filterList = new JSONArray(filters);
        for (int i = 0; i < filterList.length(); ++i) {
            JSONObject filter = filterList.getJSONObject(i);
            String root = filter.getString("root");
            PathFilterSet filterSet = new PathFilterSet(root);
            JSONArray rules = filter.getJSONArray("rules");
            for (int j = 0; j < rules.length(); ++j) {
                JSONObject rule = rules.getJSONObject(j);
                String pattern = rule.getString("pattern");
                String modifier = rule.getString("modifier");
                if ("include".equals(modifier)) {
                    filterSet.addInclude((Filter)new DefaultPathFilter(pattern));
                    continue;
                }
                if (!"exclude".equals(modifier)) continue;
                filterSet.addExclude((Filter)new DefaultPathFilter(pattern));
            }
            packFilter.add(filterSet);
        }
        def.setFilter((WorkspaceFilter)packFilter, false);
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    private static void updateThumbnail(JcrPackageDefinition def, File thumbnail) throws RepositoryException, IOException {
        if (thumbnail == null || thumbnail.length() == 0) {
            return;
        }
        Node defNode = def.getNode();
        if (defNode.hasNode("thumbnail")) {
            defNode.getNode("thumbnail").remove();
        }
        Node image = defNode.addNode("thumbnail", "nt:unstructured");
        FileInputStream in = null;
        try {
            in = FileUtils.openInputStream((File)thumbnail);
            JcrUtils.putFile((Node)image, (String)"file", (String)"image/png", (InputStream)in);
        }
        finally {
            IOUtils.closeQuietly((InputStream)in);
        }
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    private void updateScreenshots(HttpServletRequest req, JcrPackageDefinition def, HttpMultipartPost hmp) throws RepositoryException, IOException, JSONException {
        String configRaw = hmp.getParameter("screenshotConfig");
        if (StringUtils.isBlank((CharSequence)configRaw)) {
            return;
        }
        JSONArray configs = new JSONArray(configRaw);
        File[] screenshots = hmp.getFileParameterValues("screenshot");
        if (screenshots == null) {
            screenshots = new File[]{};
        }
        Tika tika = new Tika();
        Node defNode = def.getNode();
        if (defNode.hasNode("temp")) {
            defNode.getNode("temp").remove();
        }
        Node tempFolder = defNode.addNode("temp", "nt:unstructured");
        Node folder = JcrUtils.getOrAddNode((Node)defNode, (String)"screenshots", (String)"nt:unstructured");
        int fileCounter = 0;
        for (int i = 0; i < configs.length(); ++i) {
            JSONObject config = configs.getJSONObject(i);
            if (config.getBoolean("upload")) {
                if (screenshots.length > fileCounter) {
                    File screenshot = screenshots[fileCounter];
                    if (screenshot.length() == 0) continue;
                    String name = UUID.randomUUID().toString();
                    Node image = tempFolder.addNode(name, "nt:unstructured");
                    String mimeType = tika.detect(screenshot);
                    FileInputStream in = null;
                    try {
                        in = FileUtils.openInputStream((File)screenshot);
                        JcrUtils.putFile((Node)image, (String)"file", (String)mimeType, (InputStream)in);
                    }
                    finally {
                        IOUtils.closeQuietly((InputStream)in);
                    }
                }
                ++fileCounter;
                continue;
            }
            try {
                String name = UUID.randomUUID().toString();
                tempFolder.getSession().move(config.getString("path"), tempFolder.getPath() + "/" + name);
                continue;
            }
            catch (PathNotFoundException ignored) {
                // empty catch block
            }
        }
        folder.remove();
        tempFolder.getSession().move(tempFolder.getPath(), defNode.getPath() + "/screenshots");
    }

    private void updateBuiltWith(JcrPackageDefinition def) {
        ArrayList<String> versions = new ArrayList<String>();
        for (ProductInfo p : this.productInfoService.getInfos()) {
            versions.add(p.getName() + "-" + p.getVersion().toString());
        }
        def.set("builtWith", StringUtils.join(versions, (String)", "), false);
    }

    private static void write(HttpMultipartPost data, String param, JcrPackageDefinition def, String property) {
        String v = data.getParameter(param);
        if (v != null) {
            def.set(property, v, false);
        }
    }

    private static void writeBool(HttpMultipartPost data, String param, JcrPackageDefinition def, String property) {
        String v = data.getParameter(param);
        if (v != null && ("on".equals(v) || "true".equals(v))) {
            def.set(property, true, false);
        } else {
            def.set(property, (String)null, false);
        }
    }

    private static void writeMulti(HttpMultipartPost data, String param, JcrPackageDefinition def, String property) throws RepositoryException {
        String[] values = data.getParameterValues(param);
        if (values != null) {
            def.getNode().setProperty(property, values);
        } else {
            def.getNode().setProperty(property, (Value[])null);
        }
    }
}