org.xwiki.platform.patchservice.web.PatchServiceAction.java Source code

Java tutorial

Introduction

Here is the source code for org.xwiki.platform.patchservice.web.PatchServiceAction.java

Source

/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 *
 */
package org.xwiki.platform.patchservice.web;

import java.io.IOException;
import java.io.StringReader;

import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSInput;
import org.w3c.dom.ls.LSParser;
import org.xwiki.platform.patchservice.api.Patch;
import org.xwiki.platform.patchservice.api.PatchId;
import org.xwiki.platform.patchservice.impl.PatchIdImpl;
import org.xwiki.platform.patchservice.impl.PatchImpl;
import org.xwiki.platform.patchservice.plugin.PatchservicePlugin;

import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.web.XWikiAction;
import com.xpn.xwiki.web.XWikiRequest;
import com.xpn.xwiki.web.XWikiResponse;

public class PatchServiceAction extends XWikiAction {
    /** Logging helper object. */
    private static final Log LOG = LogFactory.getLog(PatchServiceAction.class);

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean action(XWikiContext context) throws XWikiException {
        try {
            XWikiRequest request = context.getRequest();
            XWikiResponse response = context.getResponse();
            PatchservicePlugin plugin = (PatchservicePlugin) context.getWiki().getPlugin("patchservice", context);
            String uri = request.getRequestURI();
            String paction = "patches/";
            System.err.println("uri: " + uri);
            String action = uri.substring(uri.indexOf(paction) + paction.length());
            if (action.startsWith("all")) {
                processAll(request, response, plugin, context);
            } else if (action.startsWith("patch")) {
                processPatch(request, response, plugin, context);
            } else if (action.startsWith("id")) {
                processId(request, response, plugin, context);
            } else if (action.startsWith("updates/id")) {
                processUpdates(request, response, plugin, context);
            } else if (action.startsWith("delta")) {
                processDelta(request, response, plugin, context);
            } else if (action.startsWith("keys")) {
                processKeys(request, response, plugin, context);
            } else if (action.startsWith("key")) {
                processKey(request, response, plugin, context);
            }
        } catch (Exception ex) {
            LOG.warn("Unhandled exception: " + ex.getMessage(), ex);
            try {
                context.getResponse().setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                context.getResponse().getWriter().print("Unhandled exception: " + ex.getMessage());
            } catch (Exception ex2) {
                // Cannot send an error message...
            }
        }
        return false;
    }

    protected void processAll(XWikiRequest request, XWikiResponse response, PatchservicePlugin plugin,
            XWikiContext context) throws Exception {
        Document doc = createEmptyDocument();
        doc.appendChild(doc.createElement("patches"));
        for (Patch p : plugin.getAllPatches()) {
            doc.getDocumentElement().appendChild(p.toXml(doc));
        }
        outputXml(doc, response);
    }

    protected void processUpdates(XWikiRequest request, XWikiResponse response, PatchservicePlugin plugin,
            XWikiContext context) throws Exception {
        if (StringUtils.isEmpty(request.getParameter("patch_id"))) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            response.getWriter().print("The request must contain a patch_id parameter.");
            return;
        }
        PatchId id = new PatchIdImpl();
        try {
            id.fromXml(parseString(request.getParameter("patch_id")).getDocumentElement());
        } catch (Exception ex) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            response.getWriter().print("Invalid patch_id parameter: " + ex.getMessage());
            return;
        }
        Document doc = createEmptyDocument();
        doc.appendChild(doc.createElement("patches"));
        for (Patch p : plugin.getUpdatesFrom(id)) {
            doc.getDocumentElement().appendChild(p.toXml(doc));
        }
        outputXml(doc, response);
    }

    protected void processDelta(XWikiRequest request, XWikiResponse response, PatchservicePlugin plugin,
            XWikiContext context) throws Exception {
        if (StringUtils.isEmpty(request.getParameter("patch_id_from"))) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            response.getWriter().print("The request must contain a patch_id_from parameter.");
            return;
        }
        if (StringUtils.isEmpty(request.getParameter("patch_id_to"))) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            response.getWriter().print("The request must contain a patch_id_from parameter.");
            return;
        }
        PatchId startId = new PatchIdImpl();
        try {
            startId.fromXml(parseString(request.getParameter("patch_id_from")).getDocumentElement());
        } catch (Exception ex) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            response.getWriter().print("Invalid patch_id_from parameter: " + ex.getMessage());
            return;
        }
        PatchId endId = new PatchIdImpl();
        try {
            endId.fromXml(parseString(request.getParameter("patch_id_to")).getDocumentElement());
        } catch (Exception ex) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            response.getWriter().print("Invalid patch_id_to parameter: " + ex.getMessage());
            return;
        }
        Document doc = createEmptyDocument();
        doc.appendChild(doc.createElement("patches"));
        for (Patch p : plugin.getDelta(startId, endId)) {
            doc.getDocumentElement().appendChild(p.toXml(doc));
        }
        outputXml(doc, response);
    }

    protected void processId(XWikiRequest request, XWikiResponse response, PatchservicePlugin plugin,
            XWikiContext context) throws Exception {
        if (StringUtils.isEmpty(request.getParameter("patch_id"))) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            response.getWriter().print("The request must contain a patch_id parameter.");
            return;
        }
        Document doc = createEmptyDocument();
        PatchId id = new PatchIdImpl();
        try {
            id.fromXml(parseString(request.getParameter("patch_id")).getDocumentElement());
        } catch (Exception ex) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            response.getWriter().print("Invalid patch_id parameter: " + ex.getMessage());
            return;
        }
        Patch p = plugin.getPatch(id);
        if (p == null) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            response.getWriter().print("No patch with the given id");
            return;
        }
        doc.appendChild(p.toXml(doc));
        outputXml(doc, response);
    }

    protected void processPatch(XWikiRequest request, XWikiResponse response, PatchservicePlugin plugin,
            XWikiContext context) throws Exception {
        if (StringUtils.isEmpty(request.getParameter("patch_id"))) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            response.getWriter().print("The request must contain a patch_id parameter.");
            return;
        }
        if (StringUtils.isEmpty(request.getParameter("patch"))) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            response.getWriter().print("The request must contain a patch parameter.");
            return;
        }
        PatchId id = new PatchIdImpl();
        try {
            id.fromXml(parseString(request.getParameter("patch_id")).getDocumentElement());
        } catch (Exception ex) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            response.getWriter().print("Invalid patch_id parameter: " + ex.getMessage());
            return;
        }
        Patch p = new PatchImpl();
        try {
            p.fromXml(parseString(request.getParameter("patch")).getDocumentElement());
        } catch (Exception ex) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            response.getWriter().print("Invalid patch parameter: " + ex.getMessage());
            return;
        }
        try {
            if (plugin.getDocumentUpdatesFrom(id).size() > 1) {
                response.setStatus(HttpServletResponse.SC_CONFLICT);
                response.getWriter().print("needs update");
                return;
            } else {
                try {
                    plugin.applyPatch(p, id, context);
                    plugin.logPatch(p);
                    response.getWriter().print("OK");
                } catch (Exception ex) {
                    response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                    response.getWriter().print("Failed to apply patch: " + ex.getMessage());
                }
            }
        } catch (IOException ex) {
            LOG.warn("Failed to send response");
        }
    }

    protected void processKeys(XWikiRequest request, XWikiResponse response, PatchservicePlugin plugin,
            XWikiContext context) throws Exception {
        response.setStatus(HttpServletResponse.SC_NOT_IMPLEMENTED);
        response.getWriter().print("Not implemented yet");
    }

    protected void processKey(XWikiRequest request, XWikiResponse response, PatchservicePlugin plugin,
            XWikiContext context) throws Exception {
        response.setStatus(HttpServletResponse.SC_NOT_IMPLEMENTED);
        response.getWriter().print("Not implemented yet");
    }

    private Document createEmptyDocument() {
        try {
            Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
            return doc;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private Document parseString(String content) {
        try {
            DOMImplementationLS lsImpl = (DOMImplementationLS) DOMImplementationRegistry.newInstance()
                    .getDOMImplementation("LS 3.0");
            LSInput input = lsImpl.createLSInput();
            input.setCharacterStream(new StringReader(content));
            LSParser p = lsImpl.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null);
            return p.parse(input);
        } catch (Exception ex) {
            return null;
        }
    }

    private void outputXml(Document doc, XWikiResponse response) {
        response.setContentType("text/xml");
        DOMImplementationLS ls = (DOMImplementationLS) doc.getImplementation();
        try {
            response.getWriter().write(ls.createLSSerializer().writeToString(doc));
        } catch (Exception e) {
        }
    }
}