com.openkm.servlet.admin.DbRepositoryViewServlet.java Source code

Java tutorial

Introduction

Here is the source code for com.openkm.servlet.admin.DbRepositoryViewServlet.java

Source

/**
 * OpenKM, Open Document Management System (http://www.openkm.com)
 * Copyright (c) 2006-2015 Paco Avila & Josep Llort
 * 
 * No bytes were intentionally harmed during the development of this application.
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

package com.openkm.servlet.admin;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.openkm.bean.ContentInfo;
import com.openkm.bean.PropertyGroup;
import com.openkm.bean.Repository;
import com.openkm.bean.form.FormElement;
import com.openkm.bean.form.Input;
import com.openkm.bean.form.Select;
import com.openkm.core.AccessDeniedException;
import com.openkm.core.Config;
import com.openkm.core.DatabaseException;
import com.openkm.core.LockException;
import com.openkm.core.MimeTypeConfig;
import com.openkm.core.ParseException;
import com.openkm.core.PathNotFoundException;
import com.openkm.core.RepositoryException;
import com.openkm.dao.NodeBaseDAO;
import com.openkm.dao.NodeDocumentDAO;
import com.openkm.dao.NodeDocumentVersionDAO;
import com.openkm.dao.NodeFolderDAO;
import com.openkm.dao.NodeMailDAO;
import com.openkm.dao.bean.NodeBase;
import com.openkm.dao.bean.NodeDocument;
import com.openkm.dao.bean.NodeDocumentVersion;
import com.openkm.dao.bean.NodeFolder;
import com.openkm.dao.bean.NodeMail;
import com.openkm.extractor.RegisteredExtractors;
import com.openkm.spring.PrincipalUtils;
import com.openkm.util.DiffMatchPatch;
import com.openkm.util.DiffMatchPatch.Diff;
import com.openkm.util.FormUtils;
import com.openkm.util.PathUtils;
import com.openkm.util.UserActivity;
import com.openkm.util.WebUtils;

/**
 * RepositoryView servlet
 */
public class DbRepositoryViewServlet extends BaseServlet {
    private static final long serialVersionUID = 1L;
    private static Logger log = LoggerFactory.getLogger(DbRepositoryViewServlet.class);

    @Override
    public void service(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
        String method = request.getMethod();

        if (checkMultipleInstancesAccess(request, response)) {
            if (method.equals(METHOD_GET)) {
                doGet(request, response);
            } else if (method.equals(METHOD_POST)) {
                doPost(request, response);
            }
        }
    }

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
        log.debug("doGet({}, {})", request, response);
        request.setCharacterEncoding("UTF-8");
        String action = WebUtils.getString(request, "action");
        String path = WebUtils.getString(request, "path");
        String uuid = WebUtils.getString(request, "uuid");
        updateSessionManager(request);

        try {
            if (uuid != null && !uuid.isEmpty()) {
                path = NodeBaseDAO.getInstance().getPathFromUuid(uuid);
            } else if (path != null && !path.isEmpty()) {
                uuid = NodeBaseDAO.getInstance().getUuidFromPath(path);
            }

            if (action.equals("unlock")) {
                unlock(uuid, path, request, response);
            } else if (action.equals("checkin")) {
                // checkin(session, path, request, response);
            } else if (action.equals("remove_content")) {
                removeContent(uuid, path, request, response);
            } else if (action.equals("remove_current")) {
                uuid = removeCurrent(uuid, path, request, response);
                path = NodeBaseDAO.getInstance().getPathFromUuid(uuid);
            } else if (action.equals("remove_pgroup")) {
                // removePropGrup(session, path, request, response);
            } else if (action.equals("edit")) {
                edit(uuid, path, request, response);
            } else if (action.equals("downloadVersion")) {
                downloadVersion(uuid, request, response);
            } else if (action.equals("diff")) {
                diff(uuid, request, response);
            } else if (action.equals("forceTextExtraction")) {
                forceTextExtraction(uuid, path, request, response);
            }

            if (!action.equals("edit") && !action.equals("downloadVersion") && !action.equals("diff")) {
                list(uuid, path, request, response);
            }
        } catch (PathNotFoundException e) {
            log.error(e.getMessage(), e);
            sendErrorRedirect(request, response, e);
        } catch (AccessDeniedException e) {
            log.error(e.getMessage(), e);
            sendErrorRedirect(request, response, e);
        } catch (LockException e) {
            log.error(e.getMessage(), e);
            sendErrorRedirect(request, response, e);
        } catch (RepositoryException e) {
            log.error(e.getMessage(), e);
            sendErrorRedirect(request, response, e);
        } catch (ParseException e) {
            log.error(e.getMessage(), e);
            sendErrorRedirect(request, response, e);
        } catch (DatabaseException e) {
            log.error(e.getMessage(), e);
            sendErrorRedirect(request, response, e);
        }
    }

    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
        log.debug("doPost({}, {})", request, response);
        request.setCharacterEncoding("UTF-8");
        String action = WebUtils.getString(request, "action");
        String path = WebUtils.getString(request, "path");
        String uuid = WebUtils.getString(request, "uuid");
        updateSessionManager(request);

        try {
            if (uuid != null && !uuid.isEmpty()) {
                path = NodeBaseDAO.getInstance().getPathFromUuid(uuid);
            } else if (path != null && !path.isEmpty()) {
                uuid = NodeBaseDAO.getInstance().getUuidFromPath(path);
            }

            if ("editPersist".equals(action)) {
                editPersist(uuid, path, request, response);
                list(uuid, path, request, response);
            }
        } catch (PathNotFoundException e) {
            log.error(e.getMessage(), e);
            sendErrorRedirect(request, response, e);
        } catch (AccessDeniedException e) {
            log.error(e.getMessage(), e);
            sendErrorRedirect(request, response, e);
        } catch (RepositoryException e) {
            log.error(e.getMessage(), e);
            sendErrorRedirect(request, response, e);
        } catch (ParseException e) {
            log.error(e.getMessage(), e);
            sendErrorRedirect(request, response, e);
        } catch (DatabaseException e) {
            log.error(e.getMessage(), e);
            sendErrorRedirect(request, response, e);
        }
    }

    /**
     * Edit node property.
     */
    private void edit(String uuid, String path, HttpServletRequest request, HttpServletResponse response)
            throws PathNotFoundException, DatabaseException, ServletException, IOException {
        log.debug("edit({}, {})", new Object[] { request, response });
        String property = WebUtils.getString(request, "property");
        String group = WebUtils.getString(request, "group");
        String value = WebUtils.getString(request, "value");
        String field = WebUtils.getString(request, "field");

        ServletContext sc = getServletContext();
        sc.setAttribute("uuid", uuid);
        sc.setAttribute("path", path);
        sc.setAttribute("field", field);
        sc.setAttribute("property", property);
        sc.setAttribute("group", group);
        sc.setAttribute("value", value);
        sc.getRequestDispatcher("/admin/db_repository_edit.jsp").forward(request, response);
        log.debug("edit: void");
    }

    /**
     * Save property
     */
    private void editPersist(String uuid, String path, HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException, PathNotFoundException, RepositoryException, AccessDeniedException,
            DatabaseException {
        log.debug("editPersist({}, {})", new Object[] { request, response });
        String property = WebUtils.getString(request, "property");
        String group = WebUtils.getString(request, "group");
        String value = WebUtils.getString(request, "value");

        Map<String, String> properties = new HashMap<String, String>();
        properties.put(property, value);
        NodeBaseDAO.getInstance().setProperties(uuid, group, properties);

        // Activity log
        UserActivity.log(PrincipalUtils.getUser(), "ADMIN_REPOSITORY_EDIT", uuid, path, property + ", " + value);
        log.debug("editPersist: void");
    }

    private void list(String uuid, String path, HttpServletRequest request, HttpServletResponse response)
            throws RepositoryException, PathNotFoundException, DatabaseException, ServletException, IOException,
            ParseException {
        log.debug("list({}, {})", new Object[] { request, response });
        String stats = WebUtils.getString(request, "stats");
        ContentInfo ci = null;

        if (uuid == null || uuid.isEmpty()) {
            path = "/" + Repository.ROOT;
            uuid = NodeBaseDAO.getInstance().getUuidFromPath(path);
        }

        // Respository stats calculation
        if (!stats.equals("")) {
            if (stats.equals("0")) {
                request.getSession().removeAttribute("stats");
            } else {
                request.getSession().setAttribute("stats", true);
            }
        }

        /*
         * if (request.getSession().getAttribute("stats") != null && node.isNodeType(Folder.TYPE)) {
         * try {
         * ci = OKMFolder.getInstance().getContentInfo(null, path);
         * } catch (AccessDeniedException e) {
         * log.warn(e.getMessage(), e);
         * } catch (com.openkm.core.RepositoryException e) {
         * log.warn(e.getMessage(), e);
         * } catch (PathNotFoundException e) {
         * log.warn(e.getMessage(), e);
         * } catch (DatabaseException e) {
         * log.warn(e.getMessage(), e);
         * }
         * }
         */

        // Activity log
        UserActivity.log(PrincipalUtils.getUser(), "ADMIN_REPOSITORY_LIST", uuid, path, null);
        ServletContext sc = getServletContext();

        if (!Config.ROOT_NODE_UUID.equals(uuid)) {
            NodeBase node = NodeBaseDAO.getInstance().findByPk(uuid);
            sc.setAttribute("node", node);
            sc.setAttribute("nodeType", getNodeType(node));
            sc.setAttribute("properties", getProperties(uuid));
            sc.setAttribute("contentInfo", ci);
            sc.setAttribute("depth", PathUtils.getDepth(path));

            if (node instanceof NodeDocument) {
                sc.setAttribute("locked", ((NodeDocument) node).isLocked());
                sc.setAttribute("history", NodeDocumentVersionDAO.getInstance().findByParent(uuid));
                sc.setAttribute("text", ((NodeDocument) node).getText());
                sc.setAttribute("textExtracted", ((NodeDocument) node).isTextExtracted());
                sc.setAttribute("mimeType", ((NodeDocument) node).getMimeType());
            }
        } else {
            sc.setAttribute("depth", 0);
        }

        sc.setAttribute("breadcrumb", createBreadcrumb(path));
        sc.setAttribute("children", getChildren(uuid));
        sc.getRequestDispatcher("/admin/db_repository_list.jsp").forward(request, response);
        log.debug("list: void");
    }

    /**
     * Remove current node.
     */
    private String removeCurrent(String uuid, String path, HttpServletRequest request, HttpServletResponse response)
            throws DatabaseException, PathNotFoundException, AccessDeniedException, LockException, IOException {
        log.debug("removeCurrent({}, {})", uuid, path);
        String parentUuid = NodeBaseDAO.getInstance().getParentUuid(uuid);

        if (NodeFolderDAO.getInstance().isValid(uuid)) {
            NodeFolderDAO.getInstance().purge(uuid, true);
        } else if (NodeDocumentDAO.getInstance().isValid(uuid)) {
            NodeDocumentDAO.getInstance().purge(uuid);
        } else if (NodeMailDAO.getInstance().isValid(uuid)) {
            NodeMailDAO.getInstance().purge(uuid);
        }

        // Activity log
        UserActivity.log(PrincipalUtils.getUser(), "ADMIN_REPOSITORY_REMOVE_CURRENT", uuid, path, null);
        log.debug("removeCurrent: {}", path);
        return parentUuid;
    }

    /**
     * Remove folder contents.
     */
    private void removeContent(String uuid, String path, HttpServletRequest request, HttpServletResponse response)
            throws PathNotFoundException, DatabaseException, AccessDeniedException, LockException, IOException {
        log.debug("removeContent({}, {})", uuid, path);
        NodeFolderDAO.getInstance().purge(uuid, false);

        // Activity log
        UserActivity.log(PrincipalUtils.getUser(), "ADMIN_REPOSITORY_REMOVE_CONTENT", uuid, path, null);
        log.debug("removeContent: void");
    }

    /**
     * Unlock document, or force it.
     */
    private void unlock(String uuid, String path, HttpServletRequest request, HttpServletResponse response)
            throws PathNotFoundException, AccessDeniedException, DatabaseException, LockException {
        log.debug("unlock({}, {})", uuid, path);
        String user = PrincipalUtils.getUser();
        NodeDocumentDAO.getInstance().unlock(user, uuid, true);

        // Activity log
        UserActivity.log(PrincipalUtils.getUser(), "ADMIN_REPOSITORY_UNLOCK", uuid, path, null);
        log.debug("unlock: void");
    }

    /**
     * Download version content.
     */
    private void downloadVersion(String uuid, HttpServletRequest request, HttpServletResponse response)
            throws FileNotFoundException, PathNotFoundException, DatabaseException, IOException {
        log.debug("downloadVersion({})", uuid);
        String name = WebUtils.getString(request, "name");
        String fileName = WebUtils.getString(request, "fileName");
        String mimeType = WebUtils.getString(request, "mimeType");
        InputStream is = NodeDocumentVersionDAO.getInstance().getVersionContentByParent(uuid, name);

        try {
            WebUtils.sendFile(request, response, fileName, mimeType, false, is);
        } finally {
            IOUtils.closeQuietly(is);
        }
    }

    /**
     * Diff with previous version.
     */
    private void diff(String uuid, HttpServletRequest request, HttpServletResponse response)
            throws DatabaseException, FileNotFoundException, PathNotFoundException, IOException {
        log.debug("diff({})", uuid);
        String oldUuid = WebUtils.getString(request, "oldUuid");
        String newName = WebUtils.getString(request, "newName");
        String mimeType = WebUtils.getString(request, "mimeType");
        NodeDocumentVersion oldVersion = NodeDocumentVersionDAO.getInstance().findByPk(oldUuid);
        String oldName = oldVersion.getName();
        InputStream oldIs = NodeDocumentVersionDAO.getInstance().getVersionContentByParent(uuid, oldName);
        InputStream newIs = NodeDocumentVersionDAO.getInstance().getVersionContentByParent(uuid, newName);
        String oldText = RegisteredExtractors.getText(mimeType, null, oldIs);
        String newText = RegisteredExtractors.getText(mimeType, null, newIs);
        IOUtils.closeQuietly(oldIs);
        IOUtils.closeQuietly(newIs);
        PrintWriter out = response.getWriter();

        // Calculate differences
        DiffMatchPatch dmp = new DiffMatchPatch();
        LinkedList<Diff> diffs = dmp.diffMain(oldText, newText);
        String diff = dmp.diffPrettyHtml(diffs).replace("&para;", "");

        // Send result
        response.setContentType(MimeTypeConfig.MIME_HTML);
        response.setCharacterEncoding("UTF-8");
        header(out, "Difference between versions", new String[][] { { "utilities.jsp", "Utilities" },
                { "DbRepositoryView?uuid=" + uuid, "Repository view" } });
        out.print(diff);
        footer(out);
    }

    /**
     * Force text extraction.
     */
    private void forceTextExtraction(String uuid, String path, HttpServletRequest request,
            HttpServletResponse response)
            throws DatabaseException, FileNotFoundException, PathNotFoundException, IOException {
        log.debug("forceTextExtraction({}, {})", uuid, path);
        NodeDocumentDAO.getInstance().resetPendingExtractionFlag(uuid);

        // Activity log
        UserActivity.log(PrincipalUtils.getUser(), "ADMIN_REPOSITORY_FORCE_TEXT_EXTRACTION", uuid, path, null);
        log.debug("forceTextExtraction: void");
    }

    /**
     * Create bread crumb for easy navigation.
     */
    private String createBreadcrumb(String path) throws UnsupportedEncodingException {
        int idx = path.lastIndexOf('/');
        if (idx > 0) {
            String name = path.substring(idx + 1);
            String parent = path.substring(0, idx);
            return createBreadcrumb(parent) + " / <a href=\"DbRepositoryView?path="
                    + URLEncoder.encode(path, "UTF-8") + "\">" + name + "</a>";
        } else {
            if (!path.substring(1).equals("")) {
                return "<a href=\"DbRepositoryView?path=/\">ROOT</a> / <a href=\"DbRepositoryView?path="
                        + URLEncoder.encode(path, "UTF-8") + "\">" + path.substring(1) + "</a>";
            } else {
                return "<a href=\"DbRepositoryView?path=/\">ROOT</a>";
            }
        }
    }

    /**
     * Get node type.
     */
    private String getNodeType(NodeBase node) {
        if (node instanceof NodeFolder) {
            return "folder";
        } else if (node instanceof NodeDocument) {
            return "document";
        } else if (node instanceof NodeMail) {
            return "mail";
        } else {
            return "unknown";
        }
    }

    /**
     * Get children from node.
     */
    private Collection<Map<String, Object>> getChildren(String uuid)
            throws RepositoryException, PathNotFoundException, DatabaseException {
        ArrayList<Map<String, Object>> al = new ArrayList<Map<String, Object>>();
        Map<String, Object> hm = new HashMap<String, Object>();

        for (NodeFolder nFld : NodeFolderDAO.getInstance().findByParent(uuid)) {
            hm = new HashMap<String, Object>();
            hm.put("name", nFld.getName());
            hm.put("uuid", nFld.getUuid());
            hm.put("nodeType", getNodeType(nFld));
            al.add(hm);
        }

        for (NodeMail nMail : NodeMailDAO.getInstance().findByParent(uuid)) {
            hm = new HashMap<String, Object>();
            hm.put("name", nMail.getName());
            hm.put("uuid", nMail.getUuid());
            hm.put("nodeType", getNodeType(nMail));
            al.add(hm);
        }

        for (NodeDocument nDoc : NodeDocumentDAO.getInstance().findByParent(uuid)) {
            hm = new HashMap<String, Object>();
            hm.put("name", nDoc.getName());
            hm.put("uuid", nDoc.getUuid());
            hm.put("nodeType", getNodeType(nDoc));
            hm.put("locked", nDoc.isLocked());
            hm.put("checkedOut", nDoc.isCheckedOut());
            // hm.put("isDocumentContent", child.isNodeType(Document.CONTENT_TYPE));
            al.add(hm);
        }

        Collections.sort(al, new ChildCmp());
        return al;
    }

    /**
     * Make child node comparable.
     */
    private class ChildCmp implements Comparator<Map<String, Object>> {
        @Override
        public int compare(Map<String, Object> arg0, Map<String, Object> arg1) {
            return ((String) arg0.get("name")).compareTo((String) arg1.get("name"));
        }
    }

    /**
     * Get properties from node
     */
    private Collection<HashMap<String, String>> getProperties(String uuid)
            throws RepositoryException, PathNotFoundException, DatabaseException, IOException, ParseException {
        Map<PropertyGroup, List<FormElement>> pgfs = FormUtils.parsePropertyGroupsForms(Config.PROPERTY_GROUPS_XML);
        ArrayList<HashMap<String, String>> al = new ArrayList<HashMap<String, String>>();

        for (String grpName : NodeBaseDAO.getInstance().getPropertyGroups(uuid)) {
            List<FormElement> pgf = FormUtils.getPropertyGroupForms(pgfs, grpName);

            if (pgf != null) {
                Map<String, String> properties = NodeBaseDAO.getInstance().getProperties(uuid, grpName);

                for (FormElement fe : pgf) {
                    String value = properties.get(fe.getName());

                    if (value != null) {
                        HashMap<String, String> hm = new HashMap<String, String>();
                        hm.put("group", grpName);
                        hm.put("name", fe.getName());
                        hm.put("field", fe.getClass().getSimpleName());
                        hm.put("type", getPropertyType(fe));
                        hm.put("value", value);
                        al.add(hm);
                    }
                }
            }
        }

        Collections.sort(al, new PropertyCmp());
        return al;
    }

    /**
     * Get property type.
     */
    private String getPropertyType(FormElement fe) {
        if (fe instanceof Input) {
            return ((Input) fe).getType();
        } else if (fe instanceof Select) {
            return ((Select) fe).getType();
        } else {
            return null;
        }
    }

    /**
     * Make properties comparable
     */
    private class PropertyCmp implements Comparator<HashMap<String, String>> {
        @Override
        public int compare(HashMap<String, String> arg0, HashMap<String, String> arg1) {
            return arg0.get("name").compareTo(arg1.get("name"));
        }
    }
}