/*
* Copyright 2000-2013 Enonic AS
* http://www.enonic.com/license
*/
package com.enonic.cms.core.content;
import java.util.Date;
import java.util.List;
import com.google.common.base.Preconditions;
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.RelatedContentResultSet;
import com.enonic.cms.core.preview.PreviewContext;
import com.enonic.cms.core.security.user.UserEntity;
public class GetRelatedContentExecutor
{
private ContentService contentService;
private UserEntity user;
private Date nowAsDate;
private PreviewContext previewContext;
private List<ContentKey> contentFilter;
private List<ContentTypeKey> contentTypeFilter;
private List<CategoryKey> categoryFilter;
private boolean categoryFilterRecursive;
private boolean includeOfflineContent = false;
private boolean requireAll = false;
private int relation;
private String query;
private String orderBy;
private int index;
private int count;
private int childrenLevel = 0;
private int parentLevel = 0;
private int parentChildrenLevel = 0;
public GetRelatedContentExecutor( ContentService contentService, Date nowAsDate, PreviewContext previewContext )
{
this.contentService = contentService;
this.nowAsDate = nowAsDate;
this.previewContext = previewContext;
}
public GetRelatedContentExecutor user( UserEntity user )
{
this.user = user;
return this;
}
public GetRelatedContentExecutor contentFilter( List<ContentKey> contentKeys )
{
Preconditions.checkNotNull( contentKeys, "contentKeys cannot be null" );
Preconditions.checkArgument( contentKeys.size() > 0, "contentKeys is empty" );
this.contentFilter = contentKeys;
return this;
}
public GetRelatedContentExecutor contentTypeFilter( List<ContentTypeKey> contentTypes )
{
Preconditions.checkNotNull( contentTypes, "contentTypes cannot be null" );
Preconditions.checkArgument( contentTypes.size() > 0, "contentTypes is empty" );
this.contentTypeFilter = contentTypes;
return this;
}
public GetRelatedContentExecutor categoryFilter( List<CategoryKey> categories, boolean recursive )
{
Preconditions.checkNotNull( categories, "categories cannot be null" );
Preconditions.checkArgument( categories.size() > 0, "categories is empty" );
this.categoryFilter = categories;
this.categoryFilterRecursive = recursive;
return this;
}
public GetRelatedContentExecutor includeOfflineContent( boolean value )
{
this.includeOfflineContent = value;
return this;
}
public GetRelatedContentExecutor requireAll( boolean value )
{
this.requireAll = value;
return this;
}
public GetRelatedContentExecutor relation( int value )
{
this.relation = value;
return this;
}
public GetRelatedContentExecutor query( String value )
{
this.query = value;
return this;
}
public GetRelatedContentExecutor orderBy( String value )
{
this.orderBy = value;
return this;
}
public GetRelatedContentExecutor index( int value )
{
this.index = value;
return this;
}
public GetRelatedContentExecutor count( int value )
{
this.count = value;
return this;
}
public GetRelatedContentExecutor childrenLevel( int value )
{
this.childrenLevel = value;
return this;
}
public GetRelatedContentExecutor parentLevel( int value )
{
this.parentLevel = value;
return this;
}
public GetRelatedContentExecutor parentChildrenLevel( int value )
{
this.parentChildrenLevel = value;
return this;
}
public GetRelatedContentResult execute()
{
Preconditions.checkNotNull( user, "user must be specified" );
Preconditions.checkNotNull( contentFilter, "contentFilter must be specified" );
Preconditions.checkArgument( contentFilter.size() > 0, "contentFilter must contain one or more content keys" );
Preconditions.checkArgument( count > 0, "count must be larger than zero" );
Preconditions.checkArgument( relation != 0, "relation must either be -1 (parents) or 1 (children)" );
final ContentResultSet givenContent = getGivenContent();
final RelatedContentResultSet relatedContentToGivenContent = getRelatedContentToGivenContent( givenContent );
final ContentResultSet contentResult = applyQueryOnRelatedContentToGivenContent( relatedContentToGivenContent );
final RelatedContentResultSet relatedContent = getRelatedContentToContentResult( contentResult );
return new GetRelatedContentResult( contentResult, relatedContent );
}
private RelatedContentResultSet getRelatedContentToContentResult( ContentResultSet mainResultContent )
{
// Get the related content of the top level content
final RelatedContentQuery relatedContentSpec = new RelatedContentQuery( nowAsDate );
relatedContentSpec.setUser( user );
relatedContentSpec.setContentResultSet( mainResultContent );
relatedContentSpec.setParentLevel( parentLevel );
relatedContentSpec.setChildrenLevel( childrenLevel );
relatedContentSpec.setParentChildrenLevel( parentChildrenLevel );
relatedContentSpec.setIncludeOnlyMainVersions( true );
if ( includeOfflineContent || previewContext.isPreviewingContent() )
{
relatedContentSpec.setFilterIncludeOfflineContent();
}
else
{
relatedContentSpec.setFilterContentOnlineAt( nowAsDate );
}
RelatedContentResultSet relatedContent = contentService.queryRelatedContent( relatedContentSpec );
if ( previewContext.isPreviewingContent() )
{
relatedContent = previewContext.getContentPreviewContext().overrideRelatedContentResultSet( relatedContent );
previewContext.getContentPreviewContext().registerContentToBeAvailableOnline( relatedContent );
}
return relatedContent;
}
private ContentResultSet applyQueryOnRelatedContentToGivenContent( RelatedContentResultSet relatedContentToGivenContent )
{
final ContentByContentQuery mainResultContentQuery = new ContentByContentQuery();
mainResultContentQuery.setUser( user );
mainResultContentQuery.setQuery( query );
mainResultContentQuery.setOrderBy( orderBy );
mainResultContentQuery.setIndex( index );
mainResultContentQuery.setCount( count );
if ( contentFilter != null )
{
mainResultContentQuery.setContentKeyFilter( relatedContentToGivenContent.getContentKeys() );
}
if ( categoryFilter != null )
{
mainResultContentQuery.setCategoryKeyFilter( categoryFilter, categoryFilterRecursive ? Integer.MAX_VALUE : 1 );
}
if ( contentTypeFilter != null )
{
mainResultContentQuery.setContentTypeFilter( contentTypeFilter );
}
if ( includeOfflineContent || previewContext.isPreviewingContent() )
{
mainResultContentQuery.setFilterIncludeOfflineContent();
}
else
{
mainResultContentQuery.setFilterContentOnlineAt( nowAsDate );
}
ContentResultSet mainResultContent = contentService.queryContent( mainResultContentQuery );
if ( previewContext.isPreviewingContent() )
{
mainResultContent = previewContext.getContentPreviewContext().overrideContentResultSet( mainResultContent );
previewContext.getContentPreviewContext().registerContentToBeAvailableOnline( mainResultContent );
}
return mainResultContent;
}
private RelatedContentResultSet getRelatedContentToGivenContent( ContentResultSet givenContent )
{
final RelatedContentResultSet relatedContentToGivenContent;
if ( requireAll && givenContent.getLength() > 1 )
{
relatedContentToGivenContent = contentService.getRelatedContentRequiresAll( user, relation, givenContent );
}
else
{
final RelatedContentQuery relatedContentToBaseContentSpec = new RelatedContentQuery( nowAsDate );
relatedContentToBaseContentSpec.setUser( user );
relatedContentToBaseContentSpec.setContentResultSet( givenContent );
relatedContentToBaseContentSpec.setParentLevel( relation < 0 ? 1 : 0 );
relatedContentToBaseContentSpec.setChildrenLevel( relation > 0 ? 1 : 0 );
relatedContentToBaseContentSpec.setParentChildrenLevel( 0 );
relatedContentToBaseContentSpec.setIncludeOnlyMainVersions( true );
if ( includeOfflineContent )
{
relatedContentToBaseContentSpec.setFilterIncludeOfflineContent();
}
relatedContentToGivenContent = contentService.queryRelatedContent( relatedContentToBaseContentSpec );
final boolean previewedContentIsAmongBaseContent = previewContext.isPreviewingContent() &&
givenContent.containsContent( previewContext.getContentPreviewContext().getContentPreviewed().getKey() );
if ( previewedContentIsAmongBaseContent )
{
// ensuring offline related content to the previewed content to be included when previewing
RelatedContentQuery relatedSpecForPreviewedContent = new RelatedContentQuery( relatedContentToBaseContentSpec );
relatedSpecForPreviewedContent.setFilterIncludeOfflineContent();
relatedSpecForPreviewedContent.setContentResultSet(
new ContentResultSetNonLazy( previewContext.getContentPreviewContext().getContentAndVersionPreviewed().getContent() ) );
RelatedContentResultSet relatedContentsForPreviewedContent =
contentService.queryRelatedContent( relatedSpecForPreviewedContent );
relatedContentToGivenContent.overwrite( relatedContentsForPreviewedContent );
previewContext.getContentPreviewContext().registerContentToBeAvailableOnline( relatedContentToGivenContent );
}
}
return relatedContentToGivenContent;
}
private ContentResultSet getGivenContent()
{
final ContentByContentQuery baseContentQuery = new ContentByContentQuery();
baseContentQuery.setContentKeyFilter( contentFilter );
baseContentQuery.setCount( contentFilter.size() );
baseContentQuery.setUser( user );
if ( includeOfflineContent )
{
baseContentQuery.setFilterIncludeOfflineContent();
}
else
{
baseContentQuery.setFilterContentOnlineAt( nowAsDate );
}
ContentResultSet baseContent = contentService.queryContent( baseContentQuery );
if ( previewContext.isPreviewingContent() )
{
baseContent = previewContext.getContentPreviewContext().applyPreviewedContentOnContentResultSet( baseContent, contentFilter );
}
return baseContent;
}
}