com.enonic.cms.store.dao.FindRelatedParentsCommand.java Source code

Java tutorial

Introduction

Here is the source code for com.enonic.cms.store.dao.FindRelatedParentsCommand.java

Source

/*
 * Copyright 2000-2013 Enonic AS
 * http://www.enonic.com/license
 */

package com.enonic.cms.store.dao;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.hibernate.Query;
import org.springframework.orm.hibernate3.HibernateTemplate;

import com.google.common.collect.Lists;

import com.enonic.cms.framework.cache.CacheFacade;
import com.enonic.cms.framework.hibernate.support.InClauseBuilder;
import com.enonic.cms.framework.hibernate.support.SelectBuilder;

import com.enonic.cms.core.content.ContentEntity;
import com.enonic.cms.core.content.ContentKey;
import com.enonic.cms.core.content.ContentMap;
import com.enonic.cms.core.content.ContentStatus;
import com.enonic.cms.core.content.ContentVersionEntity;
import com.enonic.cms.core.content.ContentVersionKey;
import com.enonic.cms.core.content.RelatedContentEntity;
import com.enonic.cms.core.content.access.ContentAccessEntity;
import com.enonic.cms.core.content.resultset.RelatedParentContent;
import com.enonic.cms.core.security.group.GroupKey;

class FindRelatedParentsCommand {
    private CacheFacade entityCache;

    private HibernateTemplate hibernateTemplate;

    FindRelatedParentsCommand(CacheFacade entityCache, HibernateTemplate hibernateTemplate) {
        this.entityCache = entityCache;
        this.hibernateTemplate = hibernateTemplate;
    }

    Collection<RelatedParentContent> execute(final RelatedParentContentQuery relatedParentContentQuery) {
        if (relatedParentContentQuery.getContents() == null
                || relatedParentContentQuery.getContents().size() == 0) {
            throw new IllegalArgumentException("Given childContentKeys must contain values");
        }

        final String hql = getRelatedParentsByKeyHQL(relatedParentContentQuery);

        final Query compiled = hibernateTemplate.getSessionFactory().getCurrentSession().createQuery(hql);
        compiled.setCacheable(false);
        compiled.setReadOnly(true);
        compiled.setParameter("deleted", 0);

        if (!relatedParentContentQuery.isIncludeOfflineContent()) {
            compiled.setParameter("timeNow",
                    relatedParentContentQuery.getNow().minuteOfHour().roundFloorCopy().toDate());
            compiled.setParameter("status", ContentStatus.APPROVED.getKey());
        }

        final List<ContentKey> childContentKeys = relatedParentContentQuery.getContents();
        for (int i = 0; i < childContentKeys.size(); i++) {
            compiled.setParameter("c" + i, childContentKeys.get(i));
        }

        if (relatedParentContentQuery.hasSecurityFilter()) {
            compiled.setParameter("one", 1);
            final List<GroupKey> securityFilter = Lists.newArrayList(relatedParentContentQuery.getSecurityFilter());
            for (int i = 0; i < securityFilter.size(); i++) {
                compiled.setParameter("g" + i, securityFilter.get(i));
            }
        }

        @SuppressWarnings({ "unchecked" })
        List<Object[]> list = compiled.list();

        final Set<ContentKey> contentKeys = new LinkedHashSet<ContentKey>(list.size());
        for (Object[] row : list) {
            contentKeys.add((ContentKey) row[2]);
        }

        final ContentMap contentMapByKey = retrieveContent(contentKeys);

        final List<RelatedParentContent> relatedChildContents = new ArrayList<RelatedParentContent>();
        for (Object[] row : list) {
            ContentKey childContentKey = (ContentKey) row[0];
            ContentVersionKey parentContentMainVersionKey = (ContentVersionKey) row[1];
            ContentKey parentContentKey = (ContentKey) row[2];
            ContentEntity parentContent = contentMapByKey.get(parentContentKey);
            RelatedParentContent relatedParentContent = new RelatedParentContent(childContentKey, parentContent,
                    parentContentMainVersionKey);
            relatedChildContents.add(relatedParentContent);
        }

        return relatedChildContents;
    }

    private String getRelatedParentsByKeyHQL(final RelatedParentContentQuery relatedParentContentQuery) {
        final SelectBuilder hqlQuery = new SelectBuilder(0);
        hqlQuery.addSelect("rc.key.childContentKey");
        hqlQuery.addSelectColumn("c.mainVersion.key");
        hqlQuery.addSelectColumn("c.key");
        hqlQuery.addFromTable(ContentVersionEntity.class.getName(), "mainVersion", SelectBuilder.NO_JOIN, null);
        hqlQuery.addFromTable(RelatedContentEntity.class.getName(), "rc", SelectBuilder.NO_JOIN, null);
        hqlQuery.addFromTable(ContentEntity.class.getName(), "c", SelectBuilder.NO_JOIN, null);

        if (relatedParentContentQuery.isIncludeOnlyMainVersions()) {
            hqlQuery.addFilter("AND", "mainVersion.key = c.mainVersion.key");
        } else {
            hqlQuery.addFilter("AND", "c.key = mainVersion.content.key");
        }

        hqlQuery.addFilter("AND", "mainVersion.key = rc.key.parentContentVersionKey");

        // the content to find parents to
        hqlQuery.addFilter("AND",
                new InClauseBuilder<ContentKey>("rc.key.childContentKey", relatedParentContentQuery.getContents()) {
                    public void appendValue(final StringBuffer sql, final ContentKey value) {
                        sql.append(":c").append(getIndex());
                    }
                }.toString());

        if (!relatedParentContentQuery.isIncludeOfflineContent()) {
            hqlQuery.addFilter("AND", "mainVersion.status = :status");
            hqlQuery.addFilter("AND", "c.availableFrom <= :timeNow");
            hqlQuery.addFilter("AND", "(c.availableTo is null OR c.availableTo > :timeNow)");
        }
        hqlQuery.addFilter("AND", "c.deleted = :deleted");
        if (relatedParentContentQuery.hasSecurityFilter()) {
            final SelectBuilder securitySubQuery = new SelectBuilder(0);
            securitySubQuery.addSelect("ca.content.key");
            securitySubQuery.addFromTable(ContentAccessEntity.class.getName(), "ca", SelectBuilder.NO_JOIN, null);
            securitySubQuery.addFilter("AND", "ca.readAccess = :one");
            securitySubQuery.addFilter("AND",
                    new InClauseBuilder<GroupKey>("ca.group.key", relatedParentContentQuery.getSecurityFilter()) {
                        public void appendValue(final StringBuffer sql, final GroupKey value) {
                            sql.append(":g").append(getIndex());
                        }
                    }.toString());
            hqlQuery.append("AND c.key IN ( " + securitySubQuery + " )");
        }
        hqlQuery.addOrderBy("c.createdAt");
        return hqlQuery.toString();
    }

    private ContentMap retrieveContent(final Set<ContentKey> contentKeys) {
        final FindContentByKeysQuerier findContentByKeysQuerier = new FindContentByKeysQuerier(
                hibernateTemplate.getSessionFactory().getCurrentSession(), ContentEagerFetches.PRESET_FOR_PORTAL,
                true);

        final FindContentByKeysCommandExecutor commandExecutor = new FindContentByKeysCommandExecutor(entityCache,
                hibernateTemplate, findContentByKeysQuerier);
        return commandExecutor.execute(new ArrayList<ContentKey>(contentKeys), false);
    }
}