org.jamwiki.servlets.AdminServlet.java Source code

Java tutorial

Introduction

Here is the source code for org.jamwiki.servlets.AdminServlet.java

Source

/**
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, version 2.1, dated February 1999.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the latest version of the GNU Lesser General
 * Public License as published by the Free Software Foundation;
 *
 * 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program (LICENSE.txt); if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package org.jamwiki.servlets;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.jamwiki.Environment;
import org.jamwiki.WikiBase;
import org.jamwiki.WikiConfiguration;
import org.jamwiki.WikiException;
import org.jamwiki.WikiMessage;
import org.jamwiki.authentication.JAMWikiAuthenticationConfiguration;
import org.jamwiki.authentication.RoleImpl;
import org.jamwiki.authentication.WikiUserDetails;
import org.jamwiki.db.WikiDatabase;
import org.jamwiki.model.VirtualWiki;
import org.jamwiki.model.WikiConfigurationObject;
import org.jamwiki.model.WikiUser;
import org.jamwiki.utils.Encryption;
import org.jamwiki.utils.SpamFilter; //import org.jamwiki.utils.WikiCache;
import org.jamwiki.utils.WikiLogger;
import org.jamwiki.utils.WikiUtil;
import org.springframework.web.servlet.ModelAndView;

/**
 * Used to provide administrative functions including changing Wiki
 * configuration settings and refreshing internal Wiki objects.
 */
public class AdminServlet extends JAMWikiServlet {

    private static final WikiLogger logger = WikiLogger.getLogger(AdminServlet.class.getName());
    /**
     * The name of the JSP file used to render the servlet output for the admin
     * maintenance configuration.
     */
    protected static final String JSP_ADMIN = "admin.jsp";
    /**
     * The name of the JSP file used to render the servlet output for the admin
     * maintenance functionality.
     */
    protected static final String JSP_ADMIN_SYSTEM = "admin-maintenance.jsp";

    /**
     * This method handles the request after its parent class receives control.
     * 
     * @param request
     *          - Standard HttpServletRequest object.
     * @param response
     *          - Standard HttpServletResponse object.
     * @return A <code>ModelAndView</code> object to be handled by the rest of the
     *         Spring framework.
     */
    protected ModelAndView handleJAMWikiRequest(HttpServletRequest request, HttpServletResponse response,
            ModelAndView next, WikiPageInfo pageInfo) throws Exception {
        String function = request.getParameter("function");
        next.addObject("function", function);
        if (StringUtils.isBlank(function) && ServletUtil.isTopic(request, "Special:Maintenance")) {
            viewAdminSystem(request, next, pageInfo);
        } else if (StringUtils.isBlank(function)) {
            viewAdmin(request, next, pageInfo, null);
        } else if (function.equals("cache")) {
            cache(request, next, pageInfo);
            // } else if (function.equals("search")) {
            // refreshIndex(request, next, pageInfo);
        } else if (function.equals("properties")) {
            properties(request, next, pageInfo);
        } else if (function.equals("virtualwiki")) {
            virtualWiki(request, next, pageInfo);
        } else if (function.equals("logitems")) {
            logItems(request, next, pageInfo);
        } else if (function.equals("recentchanges")) {
            recentChanges(request, next, pageInfo);
        } else if (function.equals("spam")) {
            spam(request, next, pageInfo);
            // } else if (function.equals("export")) {
            // exportToCsv(request, next, pageInfo);
            // } else if (function.equals("migrate")) {
            // migrateDatabase(request, next, pageInfo);
        } else if (function.equals("password")) {
            password(request, next, pageInfo);
        }
        return next;
    }

    /**
      *
      */
    private void cache(HttpServletRequest request, ModelAndView next, WikiPageInfo pageInfo) throws Exception {
        try {
            // WikiCache.initialize();
            next.addObject("message", new WikiMessage("admin.message.cache"));
        } catch (Exception e) {
            logger.severe("Failure while clearing cache", e);
            next.addObject("message", new WikiMessage("admin.cache.message.clearfailed", e.getMessage()));
        }
        viewAdminSystem(request, next, pageInfo);
    }

    /**
      *
      */
    // private void exportToCsv(HttpServletRequest request, ModelAndView next,
    // WikiPageInfo pageInfo) throws Exception {
    // try {
    // WikiDatabase.exportToCsv();
    // String outputDirectory = new
    // File(Environment.getValue(Environment.PROP_BASE_FILE_DIR),
    // "database").getPath();
    // next.addObject("message", new WikiMessage("admin.message.exportcsv",
    // outputDirectory));
    // } catch (Exception e) {
    // logger.severe("Failure while exporting database data to CSV file", e);
    // next.addObject("message", new WikiMessage("admin.message.exportcsvfail",
    // e.getMessage()));
    // }
    // viewAdminSystem(request, next, pageInfo);
    // }

    /**
      *
      */
    private void logItems(HttpServletRequest request, ModelAndView next, WikiPageInfo pageInfo) throws Exception {
        try {
            WikiBase.getDataHandler().reloadLogItems();
            next.addObject("message", new WikiMessage("admin.message.logitems"));
        } catch (Exception e) {
            logger.severe("Failure while loading log items", e);
            next.addObject("message", new WikiMessage("admin.message.logitemsfail", e.getMessage()));
        }
        viewAdminSystem(request, next, pageInfo);
    }

    /**
      *
      */
    // private void migrateDatabase(HttpServletRequest request, ModelAndView next,
    // WikiPageInfo pageInfo) throws Exception {
    // List<WikiMessage> errors = new ArrayList<WikiMessage>();
    // Properties props = new Properties();
    // try {
    // setProperty(props, request, Environment.PROP_BASE_PERSISTENCE_TYPE);
    // if
    // (props.getProperty(Environment.PROP_BASE_PERSISTENCE_TYPE).equals(WikiBase.PERSISTENCE_EXTERNAL))
    // {
    // setProperty(props, request, Environment.PROP_DB_DRIVER);
    // setProperty(props, request, Environment.PROP_DB_TYPE);
    // setProperty(props, request, Environment.PROP_DB_URL);
    // setProperty(props, request, Environment.PROP_DB_USERNAME);
    // setPassword(props, request, next, Environment.PROP_DB_PASSWORD,
    // "dbPassword");
    // } else {
    // // reverting from external database to an internal database
    // props.setProperty(Environment.PROP_BASE_FILE_DIR,
    // Environment.getValue(Environment.PROP_BASE_FILE_DIR));
    // WikiDatabase.setupDefaultDatabase(props);
    // }
    // // migrate from the current database to the new database
    // // identified by the properties
    // // Will return errors if the new database cannot be connected to,
    // // if it is already populated, or an error occurs copying the contents
    // WikiDatabase.migrateDatabase(props, errors);
    // if (this.saveProperties(request, next, pageInfo, props, errors)) {
    // next.addObject("message", new WikiMessage("admin.message.migratedatabase",
    // Environment.getValue(Environment.PROP_DB_URL)));
    // }
    // } catch (Exception e) {
    // logger.severe("Failure while migrating to a new database", e);
    // next.addObject("message", new WikiMessage("admin.message.migrationfailure",
    // e.getMessage()));
    // }
    // viewAdminSystem(request, next, pageInfo);
    // }

    /**
      *
      */
    private void password(HttpServletRequest request, ModelAndView next, WikiPageInfo pageInfo) throws Exception {
        List<WikiMessage> errors = new ArrayList<WikiMessage>();
        String userLogin = request.getParameter("passwordLogin");
        String newPassword = request.getParameter("passwordPassword");
        String confirmPassword = request.getParameter("passwordPasswordConfirm");
        try {
            WikiUser user = WikiBase.getDataHandler().lookupWikiUser(userLogin);
            if (user == null) {
                throw new WikiException(new WikiMessage("admin.password.message.invalidlogin", userLogin));
            }
            WikiUtil.validatePassword(newPassword, confirmPassword);
            String encryptedPassword = Encryption.encrypt(newPassword);
            WikiBase.getDataHandler().writeWikiUser(user, userLogin, encryptedPassword);
        } catch (WikiException e) {
            errors.add(e.getWikiMessage());
        } catch (Exception e) {
            logger.severe("Failure while updating user password", e);
            errors.add(new WikiMessage("admin.message.exportcsvfail", e.getMessage()));
        }
        if (!errors.isEmpty()) {
            next.addObject("errors", errors);
            next.addObject("passwordLogin", userLogin);
            next.addObject("passwordPassword", newPassword);
            next.addObject("passwordPasswordConfirm", confirmPassword);
        } else {
            next.addObject("message", new WikiMessage("admin.password.message.success", userLogin));
        }
        viewAdminSystem(request, next, pageInfo);
    }

    private void properties(HttpServletRequest request, ModelAndView next, WikiPageInfo pageInfo) throws Exception {
        Properties props = new Properties();
        try {
            List<WikiMessage> errors = new ArrayList<WikiMessage>();
            setProperty(props, request, Environment.PROP_SERVER_URL);
            setProperty(props, request, Environment.PROP_SITE_NAME);
            setProperty(props, request, Environment.PROP_BASE_DEFAULT_TOPIC);
            setProperty(props, request, Environment.PROP_BASE_LOGO_IMAGE);
            setProperty(props, request, Environment.PROP_BASE_META_DESCRIPTION);
            setProperty(props, request, Environment.PROP_TOPIC_EDITOR);
            setNumericProperty(props, request, Environment.PROP_IMAGE_RESIZE_INCREMENT, errors);
            setNumericProperty(props, request, Environment.PROP_MAX_TOPIC_VERSION_EXPORT, errors);
            setNumericProperty(props, request, Environment.PROP_RECENT_CHANGES_NUM, errors);
            setBooleanProperty(props, request, Environment.PROP_TOPIC_SPAM_FILTER);
            setBooleanProperty(props, request, Environment.PROP_TOPIC_USE_PREVIEW);
            setBooleanProperty(props, request, Environment.PROP_TOPIC_USE_SHOW_CHANGES);
            setBooleanProperty(props, request, Environment.PROP_PRINT_NEW_WINDOW);
            setBooleanProperty(props, request, Environment.PROP_EXTERNAL_LINK_NEW_WINDOW);
            setProperty(props, request, Environment.PROP_BASE_SEARCH_ENGINE);
            setProperty(props, request, Environment.PROP_PARSER_CLASS);
            setBooleanProperty(props, request, Environment.PROP_PARSER_TOC);
            setNumericProperty(props, request, Environment.PROP_PARSER_TOC_DEPTH, errors);
            setBooleanProperty(props, request, Environment.PROP_PARSER_ALLOW_HTML);
            setBooleanProperty(props, request, Environment.PROP_PARSER_ALLOW_JAVASCRIPT);
            setBooleanProperty(props, request, Environment.PROP_PARSER_ALLOW_TEMPLATES);
            setProperty(props, request, Environment.PROP_PARSER_SIGNATURE_USER_PATTERN);
            setProperty(props, request, Environment.PROP_PARSER_SIGNATURE_DATE_PATTERN);
            setProperty(props, request, Environment.PROP_BASE_FILE_DIR);
            setProperty(props, request, Environment.PROP_BASE_PERSISTENCE_TYPE);
            // if
            // (props.getProperty(Environment.PROP_BASE_PERSISTENCE_TYPE).equals(WikiBase.PERSISTENCE_EXTERNAL))
            // {
            // setProperty(props, request, Environment.PROP_DB_DRIVER);
            // setProperty(props, request, Environment.PROP_DB_TYPE);
            // setProperty(props, request, Environment.PROP_DB_URL);
            // setProperty(props, request, Environment.PROP_DB_USERNAME);
            // setPassword(props, request, next, Environment.PROP_DB_PASSWORD,
            // "dbPassword");
            // } else {
            // WikiDatabase.setupDefaultDatabase(props);
            // }
            setNumericProperty(props, request, Environment.PROP_DBCP_MAX_ACTIVE, errors);
            setNumericProperty(props, request, Environment.PROP_DBCP_MAX_IDLE, errors);
            setBooleanProperty(props, request, Environment.PROP_DBCP_TEST_ON_BORROW);
            setBooleanProperty(props, request, Environment.PROP_DBCP_TEST_ON_RETURN);
            setBooleanProperty(props, request, Environment.PROP_DBCP_TEST_WHILE_IDLE);
            setNumericProperty(props, request, Environment.PROP_DBCP_MIN_EVICTABLE_IDLE_TIME, errors);
            setNumericProperty(props, request, Environment.PROP_DBCP_TIME_BETWEEN_EVICTION_RUNS, errors);
            setNumericProperty(props, request, Environment.PROP_DBCP_NUM_TESTS_PER_EVICTION_RUN, errors);
            setProperty(props, request, Environment.PROP_DBCP_WHEN_EXHAUSTED_ACTION);
            String maxFileSizeString = request.getParameter(Environment.PROP_FILE_MAX_FILE_SIZE);
            if (StringUtils.isBlank(maxFileSizeString) || !StringUtils.isNumeric(maxFileSizeString)) {
                errors.add(new WikiMessage("admin.message.nonnumeric", Environment.PROP_FILE_MAX_FILE_SIZE,
                        maxFileSizeString));
            } else {
                int maxFileSizeInKB = Integer.parseInt(maxFileSizeString);
                props.setProperty(Environment.PROP_FILE_MAX_FILE_SIZE, Integer.toString(maxFileSizeInKB * 1000));
            }
            setProperty(props, request, Environment.PROP_FILE_DIR_FULL_PATH);
            setProperty(props, request, Environment.PROP_FILE_DIR_RELATIVE_PATH);
            setProperty(props, request, Environment.PROP_FILE_SERVER_URL);
            setProperty(props, request, Environment.PROP_FILE_BLACKLIST_TYPE);
            setProperty(props, request, Environment.PROP_FILE_BLACKLIST);
            setProperty(props, request, Environment.PROP_FILE_WHITELIST);
            /*
             * setProperty(props, request, Environment.PROP_EMAIL_SMTP_HOST);
             * setProperty(props, request, Environment.PROP_EMAIL_SMTP_USERNAME);
             * setPassword(props, request, next, Environment.PROP_EMAIL_SMTP_PASSWORD,
             * "smtpPassword"); setProperty(props, request,
             * Environment.PROP_EMAIL_REPLY_ADDRESS);
             */
            setNumericProperty(props, request, Environment.PROP_CACHE_INDIVIDUAL_SIZE, errors);
            setNumericProperty(props, request, Environment.PROP_CACHE_MAX_AGE, errors);
            setNumericProperty(props, request, Environment.PROP_CACHE_MAX_IDLE_AGE, errors);
            setNumericProperty(props, request, Environment.PROP_CACHE_TOTAL_SIZE, errors);
            setBooleanProperty(props, request, Environment.PROP_RSS_ALLOWED);
            setProperty(props, request, Environment.PROP_RSS_TITLE);
            errors.addAll(ServletUtil.validateSystemSettings(props));
            if (this.saveProperties(request, next, pageInfo, props, errors)) {
                next.addObject("message", new WikiMessage("admin.message.changessaved"));
            }
        } catch (Exception e) {
            logger.severe("Failure while processing property values", e);
            next.addObject("message", new WikiMessage("admin.message.propertyfailure", e.getMessage()));
        }
        viewAdmin(request, next, pageInfo, props);
    }

    /**
      *
      */
    private void recentChanges(HttpServletRequest request, ModelAndView next, WikiPageInfo pageInfo)
            throws Exception {
        try {
            WikiBase.getDataHandler().reloadRecentChanges();
            next.addObject("message", new WikiMessage("admin.message.recentchanges"));
        } catch (Exception e) {
            logger.severe("Failure while loading recent changes", e);
            next.addObject("message", new WikiMessage("admin.message.recentchangesfail", e.getMessage()));
        }
        viewAdminSystem(request, next, pageInfo);
    }

    /**
      *
      */
    // private void refreshIndex(HttpServletRequest request, ModelAndView next,
    // WikiPageInfo pageInfo) throws Exception {
    // try {
    // WikiBase.getSearchEngine().refreshIndex();
    // next.addObject("message", new WikiMessage("admin.message.indexrefreshed"));
    // } catch (Exception e) {
    // logger.severe("Failure while refreshing search index", e);
    // next.addObject("message", new WikiMessage("admin.message.searchrefresh",
    // e.getMessage()));
    // }
    // viewAdminSystem(request, next, pageInfo);
    // }

    /**
      *
      */
    private boolean saveProperties(HttpServletRequest request, ModelAndView next, WikiPageInfo pageInfo,
            Properties props, List<WikiMessage> errors) throws Exception {
        if (!errors.isEmpty()) {
            next.addObject("errors", errors);
            next.addObject("message", new WikiMessage("admin.message.changesnotsaved"));
            return false;
        }
        // all is well, save the properties
        Iterator iterator = props.keySet().iterator();
        while (iterator.hasNext()) {
            String key = (String) iterator.next();
            String value = props.getProperty(key);
            Environment.setValue(key, value);
        }
        Environment.saveProperties();
        // re-initialize to reset database settings (if needed)
        WikiUserDetails userDetails = ServletUtil.currentUserDetails();
        if (userDetails.hasRole(RoleImpl.ROLE_ANONYMOUS)) {
            throw new IllegalArgumentException("Cannot pass null or anonymous WikiUser object to setupAdminUser");
        }
        WikiUser user = ServletUtil.currentWikiUser();
        WikiBase.reset(request.getLocale(), user, user.getUsername(), null);
        JAMWikiAuthenticationConfiguration.resetJamwikiAnonymousAuthorities();
        JAMWikiAuthenticationConfiguration.resetDefaultGroupRoles();
        return true;
    }

    /**
      *
      */
    private static void setBooleanProperty(Properties props, HttpServletRequest request, String parameter) {
        boolean value = (request.getParameter(parameter) != null);
        props.setProperty(parameter, Boolean.toString(value));
    }

    /**
      *
      */
    private static void setPassword(Properties props, HttpServletRequest request, ModelAndView next,
            String parameter, String passwordParam) throws Exception {
        String value = request.getParameter(parameter);
        if (!StringUtils.isBlank(value)) {
            Encryption.setEncryptedProperty(parameter, value, props);
            next.addObject(passwordParam, request.getParameter(parameter));
        } else {
            props.setProperty(parameter, Environment.getValue(parameter));
        }
    }

    /**
      *
      */
    private static void setNumericProperty(Properties props, HttpServletRequest request, String parameter,
            List<WikiMessage> errors) {
        String value = request.getParameter(parameter);
        if (StringUtils.isBlank(value) || !StringUtils.isNumeric(value)) {
            errors.add(new WikiMessage("admin.message.nonnumeric", parameter, value));
        }
        props.setProperty(parameter, value);
    }

    /**
      *
      */
    private static void setProperty(Properties props, HttpServletRequest request, String parameter) {
        String value = request.getParameter(parameter);
        if (value == null) {
            value = "";
        }
        props.setProperty(parameter, value);
    }

    /**
      *
      */
    private void spam(HttpServletRequest request, ModelAndView next, WikiPageInfo pageInfo) throws Exception {
        try {
            SpamFilter.reload();
            next.addObject("message", new WikiMessage("admin.message.spamfilter"));
        } catch (Exception e) {
            logger.severe("Failure while reloading spam filter patterns", e);
            next.addObject("message", new WikiMessage("admin.message.spamfilterfail", e.getMessage()));
        }
        viewAdminSystem(request, next, pageInfo);
    }

    /**
      *
      */
    private void viewAdmin(HttpServletRequest request, ModelAndView next, WikiPageInfo pageInfo, Properties props)
            throws Exception {
        pageInfo.setContentJsp(JSP_ADMIN);
        pageInfo.setAdmin(true);
        pageInfo.setPageTitle(new WikiMessage("admin.title"));
        Map editors = WikiConfiguration.getInstance().getEditors();
        next.addObject("editors", editors);
        List<WikiConfigurationObject> dataHandlers = WikiConfiguration.getInstance().getDataHandlers();
        next.addObject("dataHandlers", dataHandlers);
        List<WikiConfigurationObject> searchEngines = WikiConfiguration.getInstance().getSearchEngines();
        next.addObject("searchEngines", searchEngines);
        List<WikiConfigurationObject> parsers = WikiConfiguration.getInstance().getParsers();
        next.addObject("parsers", parsers);
        LinkedHashMap<Integer, String> poolExhaustedMap = new LinkedHashMap<Integer, String>();
        poolExhaustedMap.put(Integer.valueOf(GenericObjectPool.WHEN_EXHAUSTED_FAIL),
                "admin.persistence.caption.whenexhaustedaction.fail");
        poolExhaustedMap.put(Integer.valueOf(GenericObjectPool.WHEN_EXHAUSTED_BLOCK),
                "admin.persistence.caption.whenexhaustedaction.block");
        poolExhaustedMap.put(Integer.valueOf(GenericObjectPool.WHEN_EXHAUSTED_GROW),
                "admin.persistence.caption.whenexhaustedaction.grow");
        next.addObject("poolExhaustedMap", poolExhaustedMap);
        LinkedHashMap<Integer, String> blacklistTypesMap = new LinkedHashMap<Integer, String>();
        blacklistTypesMap.put(Integer.valueOf(WikiBase.UPLOAD_ALL), "admin.upload.caption.allowall");
        blacklistTypesMap.put(Integer.valueOf(WikiBase.UPLOAD_NONE), "admin.upload.caption.allownone");
        blacklistTypesMap.put(Integer.valueOf(WikiBase.UPLOAD_BLACKLIST), "admin.upload.caption.useblacklist");
        blacklistTypesMap.put(Integer.valueOf(WikiBase.UPLOAD_WHITELIST), "admin.upload.caption.usewhitelist");
        next.addObject("blacklistTypes", blacklistTypesMap);
        if (props == null) {
            props = Environment.getInstance();
        }
        int maximumFileSize = Integer.valueOf(props.getProperty(Environment.PROP_FILE_MAX_FILE_SIZE)) / 1000;
        next.addObject("maximumFileSize", maximumFileSize);
        next.addObject("props", props);
    }

    /**
      *
      */
    private void viewAdminSystem(HttpServletRequest request, ModelAndView next, WikiPageInfo pageInfo)
            throws Exception {
        pageInfo.setContentJsp(JSP_ADMIN_SYSTEM);
        pageInfo.setAdmin(true);
        pageInfo.setPageTitle(new WikiMessage("admin.maintenance.title"));
        List<VirtualWiki> virtualWikiList = WikiBase.getDataHandler().getVirtualWikiList();
        next.addObject("wikis", virtualWikiList);
        boolean allowExport = Environment.getValue(Environment.PROP_BASE_PERSISTENCE_TYPE)
                .equals(WikiBase.PERSISTENCE_INTERNAL);
        next.addObject("allowExport", allowExport);
        List<WikiConfigurationObject> dataHandlers = WikiConfiguration.getInstance().getDataHandlers();
        next.addObject("dataHandlers", dataHandlers);
    }

    /**
      *
      */
    private void virtualWiki(HttpServletRequest request, ModelAndView next, WikiPageInfo pageInfo)
            throws Exception {
        WikiUser user = ServletUtil.currentWikiUser();
        try {
            VirtualWiki virtualWiki = new VirtualWiki();
            if (!StringUtils.isBlank(request.getParameter("virtualWikiId"))) {
                virtualWiki.setVirtualWikiId(Long.valueOf(request.getParameter("virtualWikiId")));
            }
            virtualWiki.setName(request.getParameter("name"));
            String defaultTopicName = WikiUtil.getParameterFromRequest(request, "defaultTopicName", true);
            virtualWiki.setDefaultTopicName(defaultTopicName);
            WikiBase.getDataHandler().writeVirtualWiki(virtualWiki);
            if (StringUtils.isBlank(request.getParameter("virtualWikiId"))) {
                WikiBase.getDataHandler().setupSpecialPages(request.getLocale(), user, virtualWiki);
            }
            next.addObject("message", new WikiMessage("admin.message.virtualwikiadded"));
        } catch (Exception e) {
            logger.severe("Failure while adding virtual wiki", e);
            next.addObject("message", new WikiMessage("admin.message.virtualwikifail", e.getMessage()));
        }
        viewAdminSystem(request, next, pageInfo);
    }
}