Kawai Wiki

Rev

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

package org.kawai.dao.jdbc;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.kawai.dao.PageDAO;
import org.kawai.model.Language;
import org.kawai.model.Page;
import org.kawai.model.Preview;
import org.kawai.model.Revision;
import org.kawai.model.User;
import org.mentabean.BeanSession;

/**
 * DAO class JdbcPageDAO.
 *
 * @author Sergio Oliveira
 *
 */

public class JdbcPageDAO extends AbstractJdbcDAO implements PageDAO {

        /**
         * Parametric constructor.
         * @param session BeanSession
         */

    public JdbcPageDAO(BeanSession session) {
        super(session);
    }

    /**
     * Loads the page object by id.
     * @return Page
     */

    @Override
    public Page load(int id) {

        Page p = new Page();
        p.setId(id);

        if (session.load(p)) {
            loadUsers(p);
            return p;
        }

        return null;
    }

    /**
     * Loads the page object by name and language.
     * @return Page
     */

    @Override
    public Page loadByName(String name, Language lang) {
        return loadByName(name, lang, -1);
    }

    /**
     * Loads the page object by name, language and revision.
     * @return Page
     */

    @Override
    public Page loadByName(String name, Language lang, int revision) {
        Page p = new Page();
        p.setName(name);
        p.setLanguageId(lang.getId());
        p.setDeleted(false);
        p = session.loadUnique(p);

        if (p != null) {
            if (revision >= 0) {
                Revision r = loadRevision(revision, name, lang);
                if (r != null) {
                    p.setCreatedById(r.getUserId());
                    p.setCreatedOn(r.getCreatedOn());
                    p.setModifiedById(-1);
                    p.setModifiedOn(null);
                    p.setRevision(true);
                    p.setRevisionNumber(r.getRevision());
                    p.setTitle(r.getNewTitle());
                    p.setBody(r.getNewBody());
                }
            }
            loadUsers(p);
        }
        return p;
    }

    /**
     * Loads the front page by language.
     * @return Page
     */

    @Override
    public Page loadFrontPage(Language lang) {
        Page p = new Page();
        p.setLanguageId(lang.getId());
        p.setFrontPage(true);
        p.setDeleted(false);
        p = session.loadUnique(p);
        if (p != null) {
            loadUsers(p);
        }
        return p;
    }

    private void loadUsers(Page p) {
        User modifier = new User();
        modifier.setId(p.getModifiedById());

        if (p.getModifiedById() > 0) {
            if (session.load(modifier)) {
                p.setModifiedBy(modifier);
            } else {
                throw new IllegalStateException("Cannot load user by id: " + p.getModifiedById());
            }
        }

        User creator = new User();
        creator.setId(p.getCreatedById());

        if (p.getCreatedById() > 0) {
            if (session.load(creator)) {
                p.setCreatedBy(creator);
            } else {
                throw new IllegalStateException("Cannot load user by id: " + p.getCreatedById());
            }
        }
    }

    /**
     * Updates the page on database.
     * @param p Page
     */

    @Override
    public void update(Page p) {
        session.update(p);
    }

    /**
     * Persist the page on database.
     * @param p Page
     */

    @Override
    public void insert(Page p) {
        p.setDeleted(false);
        session.insert(p);
    }

    /**
     * Checks if page exists by name and language.
     * @param name String
     * @param lang Language
     * @return boolean
     */

    @Override
    public boolean exists(String name, Language lang) {
        return loadByName(name, lang) != null;
    }

    /**
     * Checks if is system page.
     * @param name String
     * @return boolean
     */

    @Override
    public boolean isSystemPage(String name) {
        Page page = new Page();
        page.setName(name);
        page.setDeleted(false);
        List<Page> list = session.loadList(page);
        for(Page thePage : list) {
            if (thePage.isSystemPage()) return true;
        }
        return false;
    }

    /**
     * Load all page including system pages.
     * @return List < Page >
     */

    @Override
    public List<Page> loadAll(boolean includeSystemPages) {

        String[] propsToExclude = { "body" };

        PreparedStatement stmt = null;
        ResultSet rset = null;

        try {

            StringBuilder query = new StringBuilder(512);
            query.append("select ").append(session.buildSelectMinus(Page.class, "p", propsToExclude));
            query.append(", ").append(session.buildSelect(User.class, "creator"));
            query.append(", ").append(session.buildSelect(User.class, "modifier"));
            query.append(" from Pages p");
            query.append(" join Users creator on p.created_by = creator.id");
            query.append(" left join Users modifier on p.modified_by = modifier.id");
            query.append(" where p.deleted = 'F' and p.language_id in (");
           
            List<Language> langs = Language.all();
            int count = 0;
            for(Language lang : langs) {
                if (count++ > 0) query.append(",");
                query.append(lang.getId());
            }
            query.append(")");
           
            if (!includeSystemPages) {
                query.append(" and p.system_page = 'F'");
            }
            query.append(" order by p.system_page, p.front_page, p.name, p.language_id");

            stmt = conn.prepareStatement(query.toString());

            rset = stmt.executeQuery();

            List<Page> pages = new LinkedList<Page>();

            while(rset.next()) {

                Page p = new Page();
                session.populateBeanMinus(rset, p, "p", propsToExclude);

                User creator = new User();
                session.populateBean(rset, creator, "creator");
                p.setCreatedBy(creator);

                if (rset.getInt("modifier_id") > 0) {
                    User modifier = new User();
                    session.populateBean(rset, modifier, "modifier");
                    p.setModifiedBy(modifier);
                }

                pages.add(p);
            }

            return pages;

        } catch(Exception e) {
            throw new RuntimeException(e);
        } finally {
            close(stmt, rset);
        }
    }

    private Page get(List<Page> pages, Language lang) {
        for(Page p : pages) {
            if (p.getLanguage() == lang) return p;
        }
        return null;
    }

    /**
     * Sets the new front page.
     * @param p Page
     * @return boolean
     */

    @Override
    public boolean setNewFrontPage(Page p) {

        if (p.isSystemPage() || p.isFrontPage() || p.isDeleted()) return false;

        Page page = new Page();
        page.setFrontPage(true);
        page.setDeleted(false);

        List<Page> frontPages = session.loadList(page);
        Page currFrontPage = get(frontPages, p.getLanguage());

        if (currFrontPage != null) {
            // it is not front-page anymore...
            session.load(currFrontPage); // reload to attach to session...
            currFrontPage.setFrontPage(false);
            session.update(currFrontPage);
        }

        p.setFrontPage(true);
        session.update(p);

        return true;
    }

    @Override
    public boolean delete(Page p) {
        if (p.isDeleted() || p.isSystemPage() || p.isFrontPage()) return false;
        p.setDeleted(true);
        session.update(p);
        return true;
    }

    @Override
    public Preview loadPreview(int userId, String name, Language lang) {
        Preview p = new Preview();
        p.setName(name);
        p.setLanguageId(lang.getId());
        p.setUserId(userId);

        p = session.loadUnique(p);

        if (p != null) {
            User user = new User();
            user.setId(userId);
            session.load(user);
            p.setUser(user);

            Page page = loadByName(name, lang);
            if (page != null) {
                p.setNew(false);
                p.setSystemPage(page.isSystemPage());
            } else {
                p.setNew(true);
                p.setSystemPage(false);
            }
        }

        return p;
    }

    @Override
    public Preview insertPreview(int userId, Page page, String comment) {
        Preview preview = loadPreview(userId, page.getName(), page.getLanguage());
        if (preview != null) {
            preview.setTitle(page.getTitle());
            preview.setBody(page.getBody());
            preview.setComment(comment);
            session.update(preview);
        } else {
            preview = new Preview();
            preview.setName(page.getName());
            preview.setLanguageId(page.getLanguageId());
            preview.setUserId(userId);
            preview.setTitle(page.getTitle());
            preview.setBody(page.getBody());
            preview.setComment(comment);
            session.insert(preview);
        }
        return preview;
    }

    @Override
    public String getFrontPage(Language lang) {
        Page page = new Page();
        page.setLanguageId(lang.getId());
        page.setFrontPage(true);

        Page front = session.loadUnique(page);
        if (front != null) {
            return front.getName();
        }
        return null;
    }

    @Override
    public Page loadByNameWithPreview(int userId, String name, Language lang) {
        Page p = loadByName(name, lang);
        if (p == null) {
            // we may still have a preview...
            Preview preview = loadPreview(userId, name, lang);
            if (preview != null) {
                preview.setNew(true);
                return preview.getPage();
            }
            return null;
        } else {
            // check if we have a preview for this page...
            Preview preview = loadPreview(userId, name, lang);
            if (preview != null) {
                preview.setNew(false);
                p.setPreview(preview);
            }
            return p;
        }
    }

    @Override
    public void deletePreview(int userId, String name, Language lang) {
        Preview preview = loadPreview(userId, name, lang);
        if (preview != null) {
            Preview p = new Preview();
            p.setId(preview.getId());
            session.delete(p);
        }
    }

    @Override
    public Revision loadRevision(int revision, String name, Language lang) {
        Revision r = new Revision();
        r.setRevision(revision);
        r.setName(name);
        r.setLanguageId(lang.getId());
        return session.loadUnique(r);
    }

    @Override
    public void insertRevision(Revision r) {

        PreparedStatement stmt = null;
        ResultSet rset = null;

        try {

            // first time, lock whole table
            stmt = conn.prepareStatement("LOCK TABLES Revisions WRITE"); // this works as a synchronized block locked on the database... (I tested it!)
            stmt.execute();
            stmt.close();

            stmt = conn.prepareStatement("select max(revision) from Revisions where name = ? and language_id = ?");
            stmt.setString(1, r.getName());
            stmt.setInt(2, r.getLanguageId());
            rset = stmt.executeQuery();
            rset.next();
            int revisionNumber = rset.getInt(1) + 1;

            if (rset.wasNull()) {
                // inserting for the very first time... (page creatiion, not modification)
                revisionNumber = 0;
            }

            rset.close();
            stmt.close();

            r.setRevision(revisionNumber);
            session.insert(r);

            stmt = conn.prepareStatement("UNLOCK TABLES");
            stmt.execute();

        } catch(Exception e) {
            throw new RuntimeException(e);
        } finally {
            close(stmt, rset);
        }
    }

    @Override
    public List<Revision> loadRevisions(String name, Language lang) {

        String[] propsToExclude = { "oldTitle", "newTitle", "oldBody", "newBody" };

        PreparedStatement stmt = null;
        ResultSet rset = null;

        try {

            StringBuilder query = new StringBuilder(256);
            query.append("select ").append(session.buildSelectMinus(Revision.class, "r", propsToExclude));
            query.append(", ").append(session.buildSelect(User.class, "u"));
            query.append(", p.system_page p_system_page");
            query.append(", p.front_page p_front_page");
            query.append(", p.title p_title");
            query.append(" from Revisions r join Users u on r.user_id = u.id");
            query.append(" join Pages p on r.name = p.name and r.language_id = p.language_id");
            query.append(" where r.name = ? and r.language_id = ?");
            query.append(" order by revision desc");
            query.append(" limit 50");

            stmt = conn.prepareStatement(query.toString());
            stmt.setString(1, name);
            stmt.setInt(2, lang.getId());

            rset = stmt.executeQuery();

            List<Revision> revisions = new ArrayList<Revision>(50);

            while(rset.next()) {

                Revision r = new Revision();
                session.populateBeanMinus(rset, r, "r", propsToExclude);

                User u = new User();
                session.populateBean(rset, u, "u");
                r.setUser(u);

                boolean isSystemPage = rset.getString("p_system_page").equals("T");
                r.setSystemPage(isSystemPage);

                boolean isFrontPage = rset.getString("p_front_page").equals("T");
                r.setFrontPage(isFrontPage);

                String title = rset.getString("p_title");
                r.setTitle(title);

                revisions.add(r);
            }

            return revisions;
        } catch(Exception e) {
            throw new RuntimeException(e);
        } finally {
            close(stmt, rset);
        }
    }

    @Override
    public List<Revision> loadLastRevisions(Language lang, boolean includeSystemPages) {

        String[] propsToExclude = { "oldTitle", "newTitle", "oldBody", "newBody" };

        PreparedStatement stmt = null;
        ResultSet rset = null;

        try {
            StringBuilder sb = new StringBuilder(512);
            sb.append("select ").append(session.buildSelectMinus(Revision.class, "r", propsToExclude));
            sb.append(", ").append(session.buildSelect(User.class, "u"));
            sb.append(", p.system_page p_system_page");
            sb.append(", p.front_page p_front_page");
            sb.append(", p.title p_title");
            sb.append(" from Revisions r join Users u on r.user_id = u.id");
            sb.append(" join Pages p on r.name = p.name and r.language_id = p.language_id");
            sb.append(" where r.language_id = ?");
            if (!includeSystemPages) {
                sb.append(" and p.system_page = 'F'");
            }
            sb.append(" order by r.created_on desc");
            sb.append(" limit 50");

            stmt = conn.prepareStatement(sb.toString());
            stmt.setInt(1, lang.getId());

            rset = stmt.executeQuery();

            List<Revision> results = new ArrayList<Revision>(50);

            while(rset.next()) {
                Revision r = new Revision();
                session.populateBeanMinus(rset, r, "r", propsToExclude);

                User u = new User();
                session.populateBean(rset, u, "u");
                r.setUser(u);

                boolean isSystemPage = rset.getString("p_system_page").equals("T");
                r.setSystemPage(isSystemPage);

                boolean isFrontPage = rset.getString("p_front_page").equals("T");
                r.setFrontPage(isFrontPage);

                String title = rset.getString("p_title");
                r.setTitle(title);

                results.add(r);
            }

            return results;

        } catch(Exception e) {
            throw new RuntimeException(e);
        } finally {
            close(stmt, rset);
        }

    }
}