/* * Copyright 2000-2013 Enonic AS * http://www.enonic.com/license */ package com.enonic.cms.core.content; import java.util.Collection; import java.util.Set; import org.joda.time.DateTime; import com.enonic.cms.core.content.category.CategoryKey; import com.enonic.cms.core.content.contenttype.ContentTypeKey; import com.enonic.cms.core.content.query.ContentByContentQuery; import com.enonic.cms.core.content.query.RelatedContentQuery; import com.enonic.cms.core.content.resultset.ContentResultSet; import com.enonic.cms.core.content.resultset.ContentResultSetNonLazy; import com.enonic.cms.core.content.resultset.RelatedChildContent; import com.enonic.cms.core.content.resultset.RelatedContentResultSet; import com.enonic.cms.core.preview.PreviewContext; import com.enonic.cms.core.security.user.UserEntity; import com.enonic.cms.core.security.user.UserKey; import com.enonic.cms.store.dao.ContentDao; import com.enonic.cms.store.dao.UserDao; /** * Nov 16, 2010 */ public class GetContentExecutor { private ContentService contentService; private ContentDao contentDao; private UserDao userDao; private DateTime now; private PreviewContext previewContext; private UserKey user; private String query; private String orderBy; private int index; private int count; private int childrenLevel = 0; private int parentLevel = 0; private int parentChildrenLevel = 0; private Collection<ContentKey> contentFilter; private Collection<CategoryKey> categoryFilter; private int categoryLevels = 0; private Collection<ContentTypeKey> contentTypeFilter; private boolean includeOfflineContent = false; private boolean includeOfflineRelatedContent = false; private String facets; public GetContentExecutor( ContentService contentService, ContentDao contentDao, UserDao userDao, DateTime now, PreviewContext previewContext ) { this.contentService = contentService; this.contentDao = contentDao; this.userDao = userDao; this.now = now; this.previewContext = previewContext; } public GetContentExecutor user( UserKey value ) { this.user = value; return this; } public GetContentExecutor query( String value ) { this.query = value; return this; } public GetContentExecutor orderBy( String value ) { this.orderBy = value; return this; } public GetContentExecutor index( int value ) { this.index = value; return this; } public GetContentExecutor count( int value ) { this.count = value; return this; } public GetContentExecutor childrenLevel( int value ) { this.childrenLevel = value; return this; } public GetContentExecutor parentLevel( int value ) { this.parentLevel = value; return this; } public GetContentExecutor parentChildrenLevel( int value ) { this.parentChildrenLevel = value; return this; } public GetContentExecutor contentFilter( Collection<ContentKey> value ) { this.contentFilter = value; return this; } public GetContentExecutor categoryFilter( Collection<CategoryKey> value, int categoryLevels ) { this.categoryFilter = value; this.categoryLevels = categoryLevels; return this; } public GetContentExecutor contentTypeFilter( Collection<ContentTypeKey> value ) { this.contentTypeFilter = value; return this; } public GetContentExecutor includeOfflineContent() { this.includeOfflineContent = true; return this; } public GetContentExecutor includeOfflineRelatedContent() { this.includeOfflineRelatedContent = true; return this; } public GetContentExecutor facets( String facets ) { this.facets = facets; return this; } public GetContentResult execute() { ContentByContentQuery contentByContentQuery = new ContentByContentQuery(); contentByContentQuery.setQuery( query ); contentByContentQuery.setOrderBy( orderBy ); contentByContentQuery.setIndex( index ); contentByContentQuery.setCount( count ); contentByContentQuery.setUser( resolveUser( user ) ); contentByContentQuery.setContentKeyFilter( contentFilter ); contentByContentQuery.setCategoryKeyFilter( categoryFilter, categoryLevels ); contentByContentQuery.setContentTypeFilter( contentTypeFilter ); contentByContentQuery.setFacets( facets ); if ( includeOfflineContent ) { contentByContentQuery.setFilterIncludeOfflineContent(); } else { contentByContentQuery.setFilterContentOnlineAt( now.toDate() ); } ContentResultSet contents = contentService.queryContent( contentByContentQuery ); if ( previewContext.isPreviewingContent() ) { contents = previewContext.getContentPreviewContext().applyPreviewedContentOnContentResultSet( contents, contentFilter ); } RelatedContentQuery relatedContentSpec = new RelatedContentQuery( now.toDate() ); relatedContentSpec.setUser( resolveUser( user ) ); relatedContentSpec.setContentResultSet( contents ); relatedContentSpec.setParentLevel( parentLevel ); relatedContentSpec.setChildrenLevel( childrenLevel ); relatedContentSpec.setParentChildrenLevel( parentChildrenLevel ); relatedContentSpec.setIncludeOnlyMainVersions( true ); if ( includeOfflineRelatedContent ) { relatedContentSpec.setFilterIncludeOfflineContent(); } RelatedContentResultSet relatedContents = contentService.queryRelatedContent( relatedContentSpec ); if ( previewContext.isPreviewingContent() ) { RelatedContentResultSet relatedContentsForPreview = resolveRelatedContentsForPreview( relatedContentSpec, relatedContents ); previewContext.getContentPreviewContext().registerContentToBeAvailableOnline( relatedContentsForPreview ); return new GetContentResult( contents, relatedContentsForPreview ); } else { return new GetContentResult( contents, relatedContents ); } } private RelatedContentResultSet resolveRelatedContentsForPreview( RelatedContentQuery originalRelatedContentQuery, RelatedContentResultSet originalRelatedContents ) { ContentVersionKey versionPreviewedKey = previewContext.getContentPreviewContext().getVersionPreviewed().getKey(); Set<ContentKey> relatedChildrenToVersionPreviewed = previewContext.getContentPreviewContext().getVersionPreviewed().getContentData().resolveRelatedContentKeys(); // Ensure to retain only related children that are in the previewed version. originalRelatedContents.retainRelatedRootChildren( versionPreviewedKey, relatedChildrenToVersionPreviewed ); // Fetch related content that is even offline.. RelatedContentResultSet relatedContentsForPreviewedContent = fetchRelatedContentIncludingOffline( originalRelatedContentQuery ); // Ensure to retain only related children that are in the previewed version relatedContentsForPreviewedContent.retainRelatedRootChildren( versionPreviewedKey, relatedChildrenToVersionPreviewed ); // Ensure the offline content is included originalRelatedContents.overwrite( relatedContentsForPreviewedContent ); // Ensure unsaved related children are included ensureUnsavedRelatedChildrenAreIncluded( originalRelatedContents ); return previewContext.getContentPreviewContext().overrideRelatedContentResultSet( originalRelatedContents ); } private RelatedContentResultSet fetchRelatedContentIncludingOffline( final RelatedContentQuery originalRelatedContentQuery ) { final RelatedContentQuery relatedSpecForPreviewedContent = new RelatedContentQuery( originalRelatedContentQuery ); relatedSpecForPreviewedContent.setContentResultSet( new ContentResultSetNonLazy( previewContext.getContentPreviewContext().getContentAndVersionPreviewed().getContent() ) ); relatedSpecForPreviewedContent.setFilterIncludeOfflineContent(); return contentService.queryRelatedContent( relatedSpecForPreviewedContent ); } private void ensureUnsavedRelatedChildrenAreIncluded( RelatedContentResultSet originalRelatedContents ) { final ContentVersionEntity versionPreviewed = previewContext.getContentPreviewContext().getVersionPreviewed(); final ContentVersionKey versionPreviewedKey = versionPreviewed.getKey(); for ( ContentKey relatedContentKey : versionPreviewed.getContentData().resolveRelatedContentKeys() ) { ContentEntity content = contentDao.findByKey( relatedContentKey ); if ( content != null && !content.isDeleted() ) { RelatedChildContent relatedChildContent = new RelatedChildContent( versionPreviewedKey, content ); originalRelatedContents.overwriteRootRelatedChild( relatedChildContent ); } } } private UserEntity resolveUser( UserKey userKey ) { return userDao.findByKey( userKey ); } }