Kawai Wiki

Rev

Rev 206 | Rev 228 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

package org.kawai.action;

import java.util.List;

import org.kawai.dao.PageDAO;
import org.kawai.dao.UserDAO;
import org.kawai.model.Group;
import org.kawai.model.Language;
import org.kawai.model.Page;
import org.kawai.model.Preview;
import org.kawai.model.Revision;
import org.mentawai.filter.AuthenticationFree;
import org.mentawai.rule.MethodRule;
import org.mentawai.rule.RegexRule;
import org.mentawai.util.HttpUtils;
import org.mentawai.validation.Validatable;
import org.mentawai.validation.ValidationInterceptor;
import org.mentawai.validation.Validator;

/**
 * Action class LoginAction.
 *
 * @author Sergio Oliveira
 *
 */

public class PageAction extends AbstractAction implements AuthenticationFree, Validatable, ValidationInterceptor {

    /** Attriubte constant LEFT_COLUMN_KEY of PageAction. */
    public static final String LEFT_COLUMN_KEY = "leftColumn";
    /** Attribute constant LEFT_COLUMN_KEY of PageAction. */
    public static final String BODY_COLUMN_KEY = "bodyColumn";
    /** Attribute constant LEFT_COLUMN_KEY of PageAction. */
    public static final String CSS_KEY = "css";
    /** Attribute constant LEFT_COLUMN_KEY of PageAction. */
    public static final String LOGO_KEY = "logo";
    /** Attribute constant LEFT_COLUMN_KEY of PageAction. */
    public static final String JAVASCRIPT_KEY = "js";

    /**
     * Parametric constructor.
     * @param userDAO UserDAO
     * @param pageDAO PageDAO
     */

    public PageAction(UserDAO userDAO, PageDAO pageDAO) {
        super(userDAO, pageDAO);
    }

    /**
     * {@inheritDoc}
     */

    @Override
    public boolean bypassAuthentication(String method) {

        if (method == null) return true;
        if (method.equals("getCSS")) return true;
        if (method.equals("getPrintCSS")) return true;
        if (method.equals("getLastRevisions")) return true;

        return false;
    }

    /**
     * {@inheritDoc}
     */

    @Override
    public void prepareValidator(Validator val, String method) {

        if (method != null && method.equals("add") && isPost()) {

            val.requiredFields("Required field!", "newPage.name", "newPage.title", "newPage.body", "newPage.languageId");

            val.requiredLists("Required field!", "newPage.languageId");

            val.add("newPage.name", RegexRule.getInstance("[A-Za-z0-9_\\-]+"), "Invalid name for page!");

            val.add("newPage.name", MethodRule.getInstance(this, "checkPageDoesNotExist"), "This page already exists!");

            val.add("newPage.name", MethodRule.getInstance(this, "checkNotSystemPage"), "Cannot create a system page!");
        }
    }

    /**
     * {@inheritDoc}
     */

    @Override
    public boolean beforeValidation(String method) {
        return true; // go ahead with validation...
    }

    /**
     * {@inheritDoc}
     */

    @Override
    public void afterValidation(String method, boolean wasOk) {
        if (method == null) {
            return;
        }

        if (method.equals("add") && !wasOk) {
            output.setValue("showForm", method);
        }
    }

    /**
     * Checks if page does not exist.
     * @return boolean
     */

    boolean checkPageDoesNotExist() {
        Page p = input.getObject(Page.class, "newPage");
        if (p.getName() == null || p.getLanguage() == null) {
            return true;
        }
        return !pageDAO.exists(p.getName(), p.getLanguage());
    }

    /**
     * Checks if page is not system page.
     * @return boolean
     */

    boolean checkNotSystemPage() {
        Page p = input.getObject(Page.class, "newPage");
        if (p.getName() == null) {
            return true;
        }
        return !pageDAO.isSystemPage(p.getName());
    }

    /**
     * Loads the left column.
     * @param lang Language
     * @return Page
     */

    private Page loadLeftColumn(Language lang) {
        if (sessionUser != null) {
            return pageDAO.loadByNameWithPreview(sessionUser.getId(), Page.LEFT_COLUMN, lang);
        } else {
            return pageDAO.loadByName(Page.LEFT_COLUMN, lang);
        }
    }

    /**
     * Loads the logo.
     * @param lang Language
     * @return Page
     */

    private Page loadLogo(Language lang) {
        if (sessionUser != null) {
            return pageDAO.loadByNameWithPreview(sessionUser.getId(), Page.LOGO, lang);
        } else {
            return pageDAO.loadByName(Page.LOGO, lang);
        }
    }

    /**
     * Sets the logo.
     * @param lang Language
     */

    private void setLogo(Language lang) {
        Page logo = loadLogo(lang);
        output.setValue(LOGO_KEY, logo);
    }

    /**
     * Sets the left column.
     * @param lang Language
     */

    private void setLeftColumn(Language lang) {
        Page lc = loadLeftColumn(lang);
        output.setValue(LEFT_COLUMN_KEY, lc);
    }

    /**
     * Loads the css.
     * @return Page
     */

    private Page loadCSS() {
        if (sessionUser != null) {
            return pageDAO.loadByNameWithPreview(sessionUser.getId(), Page.CSS, Language.getDefault());
        } else {
            return pageDAO.loadByName(Page.CSS, Language.getDefault());
        }
    }

    /**
     * Sets the css.
     */

    private void setCSS() {
        Page css = loadCSS();
        output.setValue(CSS_KEY, css);
    }

    /**
     * Loads the javascript.
     * @return Page
     */

    private Page loadJavaScript() {
        if (sessionUser != null) {
            return pageDAO.loadByNameWithPreview(sessionUser.getId(), Page.JAVASCRIPT, Language.getDefault());
        } else {
            return pageDAO.loadByName(Page.JAVASCRIPT, Language.getDefault());
        }
    }

    /**
     * Sets the javascript.
     */

    private void setJavaScript() {
        Page js = loadJavaScript();
        output.setValue(JAVASCRIPT_KEY, js);
    }

    // for ajax
    public String get() {
        String name = input.getString("name");
        String lang = input.getString("lang");
        int revision = input.getInt("revision", -1);
        Language language = Language.fromLocale(lang);
        if (name != null && language != null) {
            Page page = pageDAO.loadByName(name, language, revision);
            if (page != null) {
                output.setValue("page", page);
            }
        }
        return AJAX;
    }

    /**
     * Gets the preview.
     * @return String
     */

    public String getPreview() {
        String name = input.getString("name");
        String lang = input.getString("lang");
        Language language = Language.fromLocale(lang);
        Page page = null;
        if (name != null && language != null) {
            if (sessionUser != null) {
                Preview preview = pageDAO.loadPreview(sessionUser.getId(), name, language);
                if (preview != null) {
                    page = preview.getPage();
                }
            }
            if (page != null) {
                output.setValue("page", page);
            }
        }
        return AJAX;
    }

    /**
     * Gets the css.
     * @return String
     */

    public String getCSS() {
        setCSS();
        return SUCCESS;
    }

    /**
     * Gets the print css.
     * @return String
     */

    public String getPrintCSS() {
        Page page = pageDAO.loadByName(Page.PRINT_CSS, Language.getDefault());
        output.setValue(CSS_KEY, page);
        return SUCCESS;
    }

    /**
     * Gets the language.
     * @return Language
     */

    private Language getLanguage() {
        return getLanguage(input.getString("lang"));
    }

    /**
     * Gets the language.
     * @param lang String
     * @return Language
     */

    private Language getLanguage(String lang) {
        if (lang == null) return language;
        Language l = Language.fromLocale(lang);
        if (l == null) return language;
        return l;
    }

    /**
     * Gets the name.
     * @return String
     */

    private String getName() {
        return getName(input.getString("name"));
    }

    /**
     * Gets the name.
     * @param name String
     * @return String
     */

    private String getName(String name) {
        if (name == null) {
            name = pageDAO.getFrontPage(language);
            if (name == null) {
                throw new IllegalStateException("There is no front page defined for language: " + language);
            }
        }
        return name;
    }
   
    /**
     * {@inheritDoc}
     */

    @Override
    public String execute() {
        String name = getName();
        Language language = getLanguage();
        int revision = input.getInt("revision", -1);
        Page page;
        if (sessionUser != null && revision == -1) {
            page = pageDAO.loadByNameWithPreview(sessionUser.getId(), name, language);
        } else {
            page = pageDAO.loadByName(name, language, revision);
        }
        if (page == null || page.isDeleted() || page.isSystemPage()) {
            return INDEX;
        }
       
        if (isPrettyURL()) {
                // check if URL is complete with the correct title...
                String correctTitle = page.getPrettyURLFormattedTitle();
                String inputTitle = input.getString("title");
                if (inputTitle == null || !inputTitle.equals(correctTitle)) {
                        String prettyURL = getPrettyURL("Page", null, name, correctTitle);
                        redir(prettyURL);
                        return SHOW;
                }
        }
       
        setCSS();
        setJavaScript();
        setLeftColumn(page.getLanguage());
        setLogo(page.getLanguage());
        output.setValue(BODY_COLUMN_KEY, page);
        return SUCCESS;
    }

    private void setPageRedirParams(Page page) {
        if (!page.isSystemPage()) {
            output.setValue("name", page.getName());
            output.setValue("lang", page.getLanguage().getLocale());
        }
    }

    /**
     * Saves the preview.
     * @return String
     */

    public String savePreview() {
        String name = input.getString("name");
        Language lang = Language.fromLocale(input.getString("lang"));
        int userId = sessionUser.getId();
        Preview preview = pageDAO.loadPreview(userId, name, lang);
        if (preview != null) {
            Page page = pageDAO.loadByName(name, lang);
            if (page != null) {

                String oldTitle = page.getTitle();
                String oldBody = page.getBody();

                page.setTitle(preview.getTitle());
                page.setBody(preview.getBody());
                page.setModifiedById(preview.getUserId());
                pageDAO.update(page);

                insertRevision(page, preview.getComment(), oldTitle, oldBody);

                pageDAO.deletePreview(userId, name, lang);
            } else {
                page = preview.getPage();
                pageDAO.insert(page);
                pageDAO.deletePreview(userId, name, lang);
                insertRevision(page, null, null, null);
            }
            setPageRedirParams(page);
        }
        return SUCCESS;
    }

    /**
     * Insert the revision.
     * @param page Page
     * @param comment String
     * @param oldTitle String
     * @param oldBody String
     */

    private void insertRevision(Page page, String comment, String oldTitle, String oldBody) {
        Revision r = new Revision();
        r.setName(page.getName());
        r.setLanguageId(page.getLanguageId());
        r.setUserId(sessionUser.getId());
        r.setNewTitle(page.getTitle());
        r.setNewBody(page.getBody());
        r.setOldTitle(oldTitle);
        r.setOldBody(oldBody);
        r.setComment(comment);
        pageDAO.insertRevision(r);
    }

    /**
     * Do the upadte.
     * @return String
     */

    public String edit() {
        if (!isPost()) return INDEX;
        String name = input.getString("name");
        String lang = input.getString("lang");
        if (name.equals("CSS")) {
            // does not make sense to have CSS in different languages...
                // (well, maybe it does, but we do NOT want to maintain more than one CSS)
            lang = "en";
        }
        Page page = pageDAO.loadByName(name, Language.fromLocale(lang));
        if (page != null) {

            String oldTitle = page.getTitle();
            String oldBody = page.getBody();

            input.inject(page);

            page.setModifiedById(sessionUser.getId());

            if (input.getBoolean("isPreview")) {
                pageDAO.insertPreview(sessionUser.getId(), page, input.getString("comment"));
            } else {
                pageDAO.update(page);

                insertRevision(page, input.getString("comment"), oldTitle, oldBody);

                // and now you have to delete the preview!
                pageDAO.deletePreview(sessionUser.getId(), page.getName(), page.getLanguage());
            }
            setPageRedirParams(page);
        }
        return UPDATED;
    }

    /**
     * Discards the preview.
     * @return String
     */

    public String discardPreview() {
        String name = input.getString("name");
        Language lang = Language.fromLocale(input.getString("lang"));
        int userId = sessionUser.getId();
        pageDAO.deletePreview(userId, name, lang);
        output.setValue("name", name);
        output.setValue("lang", lang.getLocale());
        return REMOVED;
    }

    /**
     * Add a revision.
     * @return String
     */

    public String add() {
        if (!isPost()) return INDEX;
        Page p = input.getObject(Page.class, "newPage");
        p.setCreatedById(sessionUser.getId());

        if (input.getBoolean("isPreview")) {
            pageDAO.insertPreview(sessionUser.getId(), p, null);
        } else {
            pageDAO.insert(p);
            // and now you have to delete the preview!
            pageDAO.deletePreview(sessionUser.getId(), p.getName(), p.getLanguage());
            // also add revision zero...
            insertRevision(p, null, null, null);
        }
        setPageRedirParams(p);
        return CREATED;
    }

    /**
     * List pages.
     * @return String
     */

    public String list() {
        List<Page> pages = pageDAO.loadAll(sessionUser.getGroup() == Group.ADMIN);
        output.setValue("pages", pages);
        return AJAX;
    }

    /**
     * Sets the front page.
     * @return String
     */

    public String setFrontPage() {
        int id = input.getInt("pageId");
        Page p = pageDAO.load(id);
        if (p != null) {
            if (pageDAO.setNewFrontPage(p)) {
                output.setValue("lang", p.getLang());
            }
        }
        return UPDATED;
    }

    /**
     * Removes the page.
     * @return String
     */

    public String delete() {
        int id = input.getInt("pageId");
        Page p = pageDAO.load(id);
        if (p != null) {
            pageDAO.delete(p);
        }
        return UPDATED;
    }

    /**
     * Get the revisions.
     * @return String
     */

    public String getRevisions() {
        String name = input.getString("name");
        Language lang = Language.fromLocale(input.getString("lang"));
        List<Revision> revisions = pageDAO.loadRevisions(name, lang);
        output.setValue("revisions", revisions);
        boolean isSystemPage = pageDAO.isSystemPage(name);
        output.setValue("isSystemPage", isSystemPage);
        return AJAX;
    }

    /**
     * Gets the last revisions.
     * @return String
     */

    public String getLastRevisions() {
        Language lang = Language.fromLocale(input.getString("lang"));
        List < Revision > revisions = pageDAO.loadLastRevisions(lang, sessionUser != null);
        output.setValue("revisions", revisions);
        return AJAX;
    }
}