org.apache.roller.weblogger.business.jpa.JPAWeblogManagerImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.roller.weblogger.business.jpa.JPAWeblogManagerImpl.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  The ASF licenses this file to You
 * under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.  For additional information regarding
 * copyright in this work, please see the NOTICE file in the top level
 * directory of this distribution.
 */

package org.apache.roller.weblogger.business.jpa;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.roller.weblogger.WebloggerException;
import org.apache.roller.weblogger.business.*;
import org.apache.roller.weblogger.business.pings.AutoPingManager;
import org.apache.roller.weblogger.business.pings.PingTargetManager;
import org.apache.roller.weblogger.config.WebloggerConfig;
import org.apache.roller.weblogger.pojos.*;

import javax.persistence.NoResultException;
import javax.persistence.Query;
import java.sql.Timestamp;
import java.util.*;

/*
 * JPAWeblogManagerImpl.java
 * Created on May 31, 2006, 4:08 PM
 */
@com.google.inject.Singleton
public class JPAWeblogManagerImpl implements WeblogManager {

    /** The logger instance for this class. */
    private static Log log = LogFactory.getLog(JPAWeblogManagerImpl.class);

    private static final Comparator statCountCountReverseComparator = Collections
            .reverseOrder(StatCountCountComparator.getInstance());

    private final Weblogger roller;
    private final JPAPersistenceStrategy strategy;

    // cached mapping of weblogHandles -> weblogIds
    private Map weblogHandleToIdMap = new Hashtable();

    // cached mapping of userNames -> userIds
    private Map userNameToIdMap = new Hashtable();

    @com.google.inject.Inject
    protected JPAWeblogManagerImpl(Weblogger roller, JPAPersistenceStrategy strat) {
        log.debug("Instantiating JPA Weblog Manager");
        this.roller = roller;
        this.strategy = strat;
    }

    public void release() {
    }

    /**
     * Update existing website.
     */
    public void saveWeblog(Weblog website) throws WebloggerException {

        website.setLastModified(new java.util.Date());
        strategy.store(website);
    }

    public void removeWeblog(Weblog weblog) throws WebloggerException {

        // remove contents first, then remove website
        this.removeWebsiteContents(weblog);
        this.strategy.remove(weblog);

        // remove entry from cache mapping
        this.weblogHandleToIdMap.remove(weblog.getHandle());
    }

    /**
     * convenience method for removing contents of a weblog.
     * TODO BACKEND: use manager methods instead of queries here
     */
    private void removeWebsiteContents(Weblog website) throws WebloggerException {

        UserManager umgr = roller.getUserManager();
        WeblogManager wmgr = roller.getWeblogManager();
        WeblogEntryManager emgr = roller.getWeblogEntryManager();
        BookmarkManager bmgr = roller.getBookmarkManager();
        MediaFileManager mmgr = roller.getMediaFileManager();

        //remove theme Assocs

        Query themeAssocQuery = strategy.getNamedQuery("WeblogThemeAssoc.getThemeAssocsByWeblog");
        themeAssocQuery.setParameter(1, website);
        List assocResults = themeAssocQuery.getResultList();

        for (Iterator iter = assocResults.iterator(); iter.hasNext();) {
            WeblogThemeAssoc themeAssoc = (WeblogThemeAssoc) iter.next();
            this.strategy.remove(themeAssoc);
        }

        // remove tags
        Query tagQuery = strategy.getNamedQuery("WeblogEntryTag.getByWeblog");
        tagQuery.setParameter(1, website);
        List results = tagQuery.getResultList();

        for (Iterator iter = results.iterator(); iter.hasNext();) {
            WeblogEntryTag tagData = (WeblogEntryTag) iter.next();
            if (tagData.getWeblogEntry() != null) {
                tagData.getWeblogEntry().getTags().remove(tagData);
            }
            this.strategy.remove(tagData);
        }

        // remove site tag aggregates
        List tags = emgr.getTags(website, null, null, 0, -1);
        updateTagAggregates(tags);

        // delete all weblog tag aggregates
        Query removeAggs = strategy.getNamedUpdate("WeblogEntryTagAggregate.removeByWeblog");
        removeAggs.setParameter(1, website);
        removeAggs.executeUpdate();

        // delete all bad counts
        Query removeCounts = strategy.getNamedUpdate("WeblogEntryTagAggregate.removeByTotalLessEqual");
        removeCounts.setParameter(1, new Integer(0));
        removeCounts.executeUpdate();

        // Remove the website's ping queue entries
        Query q = strategy.getNamedQuery("PingQueueEntry.getByWebsite");
        q.setParameter(1, website);
        List queueEntries = q.getResultList();
        Iterator it = queueEntries.iterator();
        while (it.hasNext()) {
            this.strategy.remove((PingQueueEntry) it.next());
        }

        // Remove the website's auto ping configurations
        AutoPingManager autoPingMgr = roller.getAutopingManager();
        List autopings = autoPingMgr.getAutoPingsByWebsite(website);
        it = autopings.iterator();
        while (it.hasNext()) {
            this.strategy.remove((AutoPing) it.next());
        }

        // Remove the website's custom ping targets
        PingTargetManager pingTargetMgr = roller.getPingTargetManager();
        List pingtargets = pingTargetMgr.getCustomPingTargets(website);
        it = pingtargets.iterator();
        while (it.hasNext()) {
            this.strategy.remove((PingTarget) it.next());
        }

        // remove associated referers
        Query refQuery2 = strategy.getNamedQuery("WeblogReferrer.getByWebsite");
        refQuery2.setParameter(1, website);
        List referers = refQuery2.getResultList();
        for (Iterator iter = referers.iterator(); iter.hasNext();) {
            WeblogReferrer referer = (WeblogReferrer) iter.next();
            this.strategy.remove(referer.getClass(), referer.getId());
        }
        // TODO: can we eliminate this unnecessary flush with OpenJPA 1.0
        this.strategy.flush();

        // remove associated pages
        Query pageQuery = strategy.getNamedQuery("WeblogTemplate.getByWebsite");
        pageQuery.setParameter(1, website);
        List pages = pageQuery.getResultList();
        for (Iterator iter = pages.iterator(); iter.hasNext();) {
            WeblogTemplate page = (WeblogTemplate) iter.next();

            //remove associated templateCode objects
            this.removeTemplateCodeObjs(page);

            this.strategy.remove(page);
        }

        // remove folders (including bookmarks)
        WeblogBookmarkFolder rootFolder = bmgr.getRootFolder(website);
        if (null != rootFolder) {
            this.strategy.remove(rootFolder);
        }
        this.strategy.flush();

        // remove mediafile metadata
        // remove uploaded files
        MediaFileManager mfmgr = WebloggerFactory.getWeblogger().getMediaFileManager();
        mfmgr.removeAllFiles(website);
        //List<MediaFileDirectory> dirs = mmgr.getMediaFileDirectories(website);
        //for (MediaFileDirectory dir : dirs) {
        //this.strategy.remove(dir);
        //}
        this.strategy.flush();

        // remove entries
        Query refQuery = strategy.getNamedQuery("WeblogEntry.getByWebsite");
        refQuery.setParameter(1, website);
        List entries = refQuery.getResultList();
        for (Iterator iter = entries.iterator(); iter.hasNext();) {
            WeblogEntry entry = (WeblogEntry) iter.next();
            emgr.removeWeblogEntry(entry);
        }
        this.strategy.flush();

        // remove categories
        WeblogCategory rootCat = emgr.getRootWeblogCategory(website);
        if (null != rootCat) {
            this.strategy.remove(rootCat);
        }

        // remove permissions
        for (Iterator iterator = umgr.getWeblogPermissions(website).iterator(); iterator.hasNext();) {
            WeblogPermission perm = (WeblogPermission) iterator.next();
            umgr.revokeWeblogPermission(perm.getWeblog(), perm.getUser(), WeblogPermission.ALL_ACTIONS);
        }

        // flush the changes before returning. This is required as there is a
        // circular dependency between WeblogCategory and Weblog
        this.strategy.flush();
    }

    protected void updateTagAggregates(List tags) throws WebloggerException {
        for (Iterator iter = tags.iterator(); iter.hasNext();) {
            TagStat stat = (TagStat) iter.next();
            Query query = strategy
                    .getNamedUpdate("WeblogEntryTagAggregate.getByName&WebsiteNullOrderByLastUsedDesc");
            query.setParameter(1, stat.getName());
            try {
                WeblogEntryTagAggregate agg = (WeblogEntryTagAggregate) query.getSingleResult();
                agg.setTotal(agg.getTotal() - stat.getCount());
            } catch (NoResultException ignored) {
            } // no agg to be updated
        }
    }

    /**
     * @see org.apache.roller.weblogger.model.UserManager#storePage(org.apache.roller.weblogger.pojos.WeblogTemplate)
     */
    public void savePage(WeblogTemplate page) throws WebloggerException {
        this.strategy.store(page);

        // update weblog last modified date.  date updated by saveWebsite()
        roller.getWeblogManager().saveWeblog(page.getWebsite());
    }

    public void saveTemplateCode(WeblogThemeTemplateCode templateCode) throws WebloggerException {
        this.strategy.store(templateCode);
        // update of the template should happen by saving template page.
    }

    public void removePage(WeblogTemplate page) throws WebloggerException {
        //remove template code objects
        this.removeTemplateCodeObjs(page);

        this.strategy.remove(page);
        // update weblog last modified date.  date updated by saveWebsite()
        roller.getWeblogManager().saveWeblog(page.getWebsite());
    }

    public void addWeblog(Weblog newWeblog) throws WebloggerException {

        this.strategy.store(newWeblog);
        this.strategy.flush();
        this.addWeblogContents(newWeblog);
    }

    private void addWeblogContents(Weblog newWeblog) throws WebloggerException {

        // grant weblog creator ADMIN permission
        List<String> actions = new ArrayList<String>();
        actions.add(WeblogPermission.ADMIN);
        roller.getUserManager().grantWeblogPermission(newWeblog, newWeblog.getCreator(), actions);

        // add default category
        WeblogCategory rootCat = new WeblogCategory(newWeblog, // newWeblog
                null, // parent
                "root", // name
                "root", // description
                null); // image
        this.strategy.store(rootCat);

        String cats = WebloggerConfig.getProperty("newuser.categories");
        WeblogCategory firstCat = rootCat;
        if (cats != null && cats.trim().length() > 0) {
            String[] splitcats = cats.split(",");
            for (int i = 0; i < splitcats.length; i++) {
                WeblogCategory c = new WeblogCategory(newWeblog, // newWeblog
                        rootCat, // parent
                        splitcats[i], // name
                        splitcats[i], // description
                        null); // image
                if (i == 0)
                    firstCat = c;
                rootCat.getWeblogCategories().add(c);
                this.strategy.store(c);
            }
        }

        // Use first category as default for Blogger API
        newWeblog.setBloggerCategory(firstCat);

        // But default category for weblog itself should be  root
        newWeblog.setDefaultCategory(rootCat);

        this.strategy.store(newWeblog);

        // add default bookmarks
        WeblogBookmarkFolder root = new WeblogBookmarkFolder(null, "root", "root", newWeblog);
        this.strategy.store(root);

        Integer zero = new Integer(0);
        String blogroll = WebloggerConfig.getProperty("newuser.blogroll");
        if (blogroll != null) {
            String[] splitroll = blogroll.split(",");
            for (int i = 0; i < splitroll.length; i++) {
                String[] rollitems = splitroll[i].split("\\|");
                if (rollitems != null && rollitems.length > 1) {
                    WeblogBookmark b = new WeblogBookmark(root, // parent
                            rollitems[0], // name
                            "", // description
                            rollitems[1].trim(), // url
                            null, // feedurl
                            zero, // weight
                            zero, // priority
                            null); // image
                    this.strategy.store(b);
                    root.getBookmarks().add(b);
                }
            }
        }

        roller.getMediaFileManager().createRootMediaFileDirectory(newWeblog);

        // flush so that all data up to this point can be available in db
        this.strategy.flush();

        // add any auto enabled ping targets
        PingTargetManager pingTargetMgr = roller.getPingTargetManager();
        AutoPingManager autoPingMgr = roller.getAutopingManager();

        Iterator pingTargets = pingTargetMgr.getCommonPingTargets().iterator();
        PingTarget pingTarget = null;
        while (pingTargets.hasNext()) {
            pingTarget = (PingTarget) pingTargets.next();

            if (pingTarget.isAutoEnabled()) {
                AutoPing autoPing = new AutoPing(null, pingTarget, newWeblog);
                autoPingMgr.saveAutoPing(autoPing);
            }
        }

    }

    public Weblog getWeblog(String id) throws WebloggerException {
        return (Weblog) this.strategy.load(Weblog.class, id);
    }

    public Weblog getWeblogByHandle(String handle) throws WebloggerException {
        return getWeblogByHandle(handle, Boolean.TRUE);
    }

    /**
     * Return website specified by handle.
     */
    public Weblog getWeblogByHandle(String handle, Boolean enabled) throws WebloggerException {

        if (handle == null)
            throw new WebloggerException("Handle cannot be null");

        // check cache first
        // NOTE: if we ever allow changing handles then this needs updating
        if (this.weblogHandleToIdMap.containsKey(handle)) {

            Weblog weblog = this.getWeblog((String) this.weblogHandleToIdMap.get(handle));
            if (weblog != null) {
                // only return weblog if enabled status matches
                if (enabled == null || enabled.equals(weblog.getEnabled())) {
                    log.debug("weblogHandleToId CACHE HIT - " + handle);
                    return weblog;
                }
            } else {
                // mapping hit with lookup miss?  mapping must be old, remove it
                this.weblogHandleToIdMap.remove(handle);
            }
        }

        Query query = strategy.getNamedQuery("Weblog.getByHandle");
        query.setParameter(1, handle);
        Weblog website = null;
        try {
            website = (Weblog) query.getSingleResult();
        } catch (NoResultException e) {
            website = null;
        }

        // add mapping to cache
        if (website != null) {
            log.debug("weblogHandleToId CACHE MISS - " + handle);
            this.weblogHandleToIdMap.put(website.getHandle(), website.getId());
        }

        if (website != null && (enabled == null || enabled.equals(website.getEnabled()))) {
            return website;
        } else {
            return null;
        }
    }

    /**
     * Get websites of a user
     */
    public List getWeblogs(Boolean enabled, Boolean active, Date startDate, Date endDate, int offset, int length)
            throws WebloggerException {

        //if (endDate == null) endDate = new Date();

        List params = new ArrayList();
        int size = 0;
        StringBuffer queryString = new StringBuffer();
        StringBuffer whereClause = new StringBuffer();

        queryString.append("SELECT w FROM Weblog w WHERE ");

        if (startDate != null) {
            Timestamp start = new Timestamp(startDate.getTime());
            if (whereClause.length() > 0)
                whereClause.append(" AND ");
            params.add(size++, start);
            whereClause.append(" w.dateCreated > ?" + size);
        }
        if (endDate != null) {
            Timestamp end = new Timestamp(endDate.getTime());
            if (whereClause.length() > 0)
                whereClause.append(" AND ");
            params.add(size++, end);
            whereClause.append(" w.dateCreated < ?" + size);
        }
        if (enabled != null) {
            if (whereClause.length() > 0)
                whereClause.append(" AND ");
            params.add(size++, enabled);
            whereClause.append(" w.enabled = ?" + size);
        }
        if (active != null) {
            if (whereClause.length() > 0)
                whereClause.append(" AND ");
            params.add(size++, active);
            whereClause.append(" w.active = ?" + size);
        }

        whereClause.append(" ORDER BY w.dateCreated DESC");

        Query query = strategy.getDynamicQuery(queryString.toString() + whereClause.toString());
        if (offset != 0) {
            query.setFirstResult(offset);
        }
        if (length != -1) {
            query.setMaxResults(length);
        }
        for (int i = 0; i < params.size(); i++) {
            query.setParameter(i + 1, params.get(i));
        }

        return query.getResultList();
    }

    public WeblogThemeAssoc getThemeAssoc(Weblog weblog, String type) throws WebloggerException {

        if (weblog == null) {
            throw new WebloggerException("Weblog is null");
        }
        if (type == null) {
            throw new WebloggerException("Type is null");
        }
        Query query = strategy.getNamedQuery("WeblogThemeAssoc.getThemeAssocByType");
        query.setParameter(1, weblog);
        query.setParameter(2, type);

        return (WeblogThemeAssoc) query.getSingleResult();
    }

    public void saveThemeAssoc(WeblogThemeAssoc themeAssoc) throws WebloggerException {
        this.strategy.store(themeAssoc);

        // update weblog last modified date.  date updated by saveWebsite()
        roller.getWeblogManager().saveWeblog(themeAssoc.getWeblog());
    }

    public List getUserWeblogs(User user, boolean enabledOnly) throws WebloggerException {
        List weblogs = new ArrayList();
        List<WeblogPermission> perms = roller.getUserManager().getWeblogPermissions(user);
        for (WeblogPermission perm : perms) {
            Weblog weblog = perm.getWeblog();
            if (!enabledOnly || weblog.getEnabled().booleanValue()) {
                if (weblog.getActive() != null && weblog.getActive().booleanValue()) {
                    weblogs.add(weblog);
                }
            }
        }
        return weblogs;
    }

    public List getWeblogUsers(Weblog weblog, boolean enabledOnly) throws WebloggerException {
        List users = new ArrayList();
        List<WeblogPermission> perms = roller.getUserManager().getWeblogPermissions(weblog);
        for (WeblogPermission perm : perms) {
            User user = perm.getUser();
            if (user == null) {
                log.error("ERROR user is null, userName:" + perm.getUserName());
                continue;
            }
            if (!enabledOnly || user.getEnabled().booleanValue()) {
                users.add(user);
            }
        }
        return users;
    }

    public WeblogTemplate getPage(String id) throws WebloggerException {
        // Don't hit database for templates stored on disk
        if (id != null && id.endsWith(".vm"))
            return null;

        return (WeblogTemplate) this.strategy.load(WeblogTemplate.class, id);
    }

    /**
     * Use JPA directly because Weblogger's Query API does too much allocation.
     */
    public WeblogTemplate getPageByLink(Weblog website, String pagelink) throws WebloggerException {

        if (website == null)
            throw new WebloggerException("userName is null");

        if (pagelink == null)
            throw new WebloggerException("Pagelink is null");

        Query query = strategy.getNamedQuery("WeblogTemplate.getByWebsite&Link");
        query.setParameter(1, website);
        query.setParameter(2, pagelink);
        try {
            return (WeblogTemplate) query.getSingleResult();
        } catch (NoResultException e) {
            return null;
        }
    }

    /**
     * @see org.apache.roller.weblogger.model.UserManager#getPageByAction(Weblog, java.lang.String)
     */
    public WeblogTemplate getPageByAction(Weblog website, String action) throws WebloggerException {

        if (website == null)
            throw new WebloggerException("website is null");

        if (action == null)
            throw new WebloggerException("Action name is null");

        Query query = strategy.getNamedQuery("WeblogTemplate.getByAction");
        query.setParameter(1, website);
        query.setParameter(2, action);
        try {
            return (WeblogTemplate) query.getSingleResult();
        } catch (NoResultException e) {
            return null;
        }
    }

    /**
     * @see org.apache.roller.weblogger.model.UserManager#getPageByName(Weblog, java.lang.String)
     */
    public WeblogTemplate getPageByName(Weblog website, String pagename) throws WebloggerException {

        if (website == null)
            throw new WebloggerException("website is null");

        if (pagename == null)
            throw new WebloggerException("Page name is null");

        Query query = strategy.getNamedQuery("WeblogTemplate.getByWebsite&Name");
        query.setParameter(1, website);
        query.setParameter(2, pagename);
        try {
            return (WeblogTemplate) query.getSingleResult();
        } catch (NoResultException e) {
            return null;
        }
    }

    public WeblogThemeTemplateCode getTemplateCodeByType(String templateId, String type) throws WebloggerException {
        if (templateId == null)
            throw new WebloggerException("Template Name is null");

        if (type == null) {
            throw new WebloggerException("Type is null");
        }

        Query query = strategy.getNamedQuery("WeblogThemeTemplateCode.getTemplateCodeByType");
        query.setParameter(1, templateId);
        query.setParameter(2, type);
        try {
            return (WeblogThemeTemplateCode) query.getSingleResult();
        } catch (NoResultException e) {
            return null;
        }
    }

    /**
     * @see org.apache.roller.weblogger.model.UserManager#getPages(Weblog)
     */
    public List getPages(Weblog website) throws WebloggerException {
        if (website == null)
            throw new WebloggerException("website is null");
        Query q = strategy.getNamedQuery("WeblogTemplate.getByWebsiteOrderByName");
        q.setParameter(1, website);
        return q.getResultList();
    }

    public Map getWeblogHandleLetterMap() throws WebloggerException {
        String lc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        Map results = new TreeMap();
        Query query = strategy.getNamedQuery("Weblog.getCountByHandleLike");
        for (int i = 0; i < 26; i++) {
            char currentChar = lc.charAt(i);
            query.setParameter(1, currentChar + "%");
            List row = query.getResultList();
            Long count = (Long) row.get(0);
            results.put(String.valueOf(currentChar), count);
        }
        return results;
    }

    public List getWeblogsByLetter(char letter, int offset, int length) throws WebloggerException {
        Query query = strategy.getNamedQuery("Weblog.getByLetterOrderByHandle");
        query.setParameter(1, letter + "%");
        if (offset != 0) {
            query.setFirstResult(offset);
        }
        if (length != -1) {
            query.setMaxResults(length);
        }
        return query.getResultList();
    }

    public List getMostCommentedWeblogs(Date startDate, Date endDate, int offset, int length)
            throws WebloggerException {

        Query query = null;

        if (endDate == null)
            endDate = new Date();

        if (startDate != null) {
            Timestamp start = new Timestamp(startDate.getTime());
            Timestamp end = new Timestamp(endDate.getTime());
            query = strategy.getNamedQuery("WeblogEntryComment.getMostCommentedWebsiteByEndDate&StartDate");
            query.setParameter(1, end);
            query.setParameter(2, start);
        } else {
            Timestamp end = new Timestamp(endDate.getTime());
            query = strategy.getNamedQuery("WeblogEntryComment.getMostCommentedWebsiteByEndDate");
            query.setParameter(1, end);
        }
        if (offset != 0) {
            query.setFirstResult(offset);
        }
        if (length != -1) {
            query.setMaxResults(length);
        }
        List queryResults = query.getResultList();
        List results = new ArrayList();
        for (Iterator iter = queryResults.iterator(); iter.hasNext();) {
            Object[] row = (Object[]) iter.next();
            StatCount sc = new StatCount((String) row[1], // website id
                    (String) row[2], // website handle
                    (String) row[3], // website name
                    "statCount.weblogCommentCountType", // stat type
                    ((Long) row[0]).longValue()); // # comments
            sc.setWeblogHandle((String) row[2]);
            results.add(sc);
        }
        // Original query ordered by desc # comments.
        // JPA QL doesn't allow queries to be ordered by agregates; do it in memory
        Collections.sort(results, statCountCountReverseComparator);

        return results;
    }

    /**
     * Get count of weblogs, active and inactive
     */
    public long getWeblogCount() throws WebloggerException {
        long ret = 0;
        List results = strategy.getNamedQuery("Weblog.getCountAllDistinct").getResultList();

        ret = ((Long) results.get(0)).longValue();

        return ret;
    }

    private void removeTemplateCodeObjs(WeblogTemplate page) throws WebloggerException {
        Query codeQuery = strategy.getNamedQuery("WeblogThemeTemplateCode.getTemplateCodesByTemplateId");
        codeQuery.setParameter(1, page.getId());
        List codeList = codeQuery.getResultList();

        for (Iterator itr = codeList.iterator(); itr.hasNext();) {
            WeblogThemeTemplateCode templateCode = (WeblogThemeTemplateCode) itr.next();
            this.strategy.remove(templateCode);
        }

    }

}