/*
* Copyright 2000-2013 Enonic AS
* http://www.enonic.com/license
*/
package com.enonic.cms.core.content;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.joda.time.DateTime;
import org.springframework.util.Assert;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.enonic.cms.core.content.access.ContentAccessEntity;
import com.enonic.cms.core.content.access.ContentAccessRightsAccumulated;
import com.enonic.cms.core.content.access.ContentAccessType;
import com.enonic.cms.core.content.category.CategoryEntity;
import com.enonic.cms.core.content.contenttype.ContentTypeEntity;
import com.enonic.cms.core.language.LanguageEntity;
import com.enonic.cms.core.security.group.GroupEntity;
import com.enonic.cms.core.security.group.GroupKey;
import com.enonic.cms.core.security.group.GroupKeyComparator;
import com.enonic.cms.core.security.user.UserEntity;
import com.enonic.cms.core.structure.SiteKey;
import com.enonic.cms.core.structure.menuitem.ContentHomeEntity;
import com.enonic.cms.core.structure.menuitem.ContentHomeKey;
import com.enonic.cms.core.structure.menuitem.MenuItemComparatorByHierarchy;
import com.enonic.cms.core.structure.menuitem.MenuItemEntity;
import com.enonic.cms.core.structure.menuitem.MenuItemKey;
import com.enonic.cms.core.structure.menuitem.section.SectionContentEntity;
public class ContentEntity
implements Serializable
{
private ContentKey key;
private Date createdAt;
private Date timestamp;
private Integer deleted;
private String name;
private Integer priority;
private Date availableFrom;
private Date availableTo;
private UserEntity owner;
private UserEntity assignee;
private UserEntity assigner;
private Date assignmentDueDate;
private String assignmentDescription;
private CategoryEntity category;
private LanguageEntity language;
private ContentEntity source;
@SuppressWarnings({"JpaModelErrorInspection"})
private ContentVersionEntity mainVersion;
private ContentVersionEntity draftVersion;
private SortedMap<Integer, ContentHomeEntity> contentHomes = new TreeMap<Integer, ContentHomeEntity>();
private List<ContentVersionEntity> versions = new ArrayList<ContentVersionEntity>();
private Set<ContentVersionEntity> relatedParents = new HashSet<ContentVersionEntity>();
private Set<SectionContentEntity> sectionContents = new HashSet<SectionContentEntity>();
private SortedSet<MenuItemEntity> directMenuItemPlacements = new TreeSet<MenuItemEntity>( new MenuItemComparatorByHierarchy() );
private SortedMap<GroupKey, ContentAccessEntity> contentAccessRights =
new TreeMap<GroupKey, ContentAccessEntity>( new GroupKeyComparator() );
public ContentEntity()
{
// Default constructor used by Hibernate.
}
/**
* Constructor that creates a new instance as a copy of the given content.
*/
public ContentEntity( ContentEntity source )
{
this();
this.key = source.getKey();
this.createdAt = source.getCreatedAt();
this.timestamp = source.getTimestamp();
this.deleted = source.getDeleted();
this.name = source.getName();
this.priority = source.getPriority();
this.availableFrom = source.getAvailableFrom();
this.availableTo = source.getAvailableTo();
this.owner = source.getOwner();
this.assignee = source.getAssignee();
this.assigner = source.getAssigner();
this.assignmentDueDate = source.getAssignmentDueDate();
this.assignmentDescription = source.getAssignmentDescription();
this.category = source.getCategory();
this.language = source.getLanguage();
this.source = source.getSource();
this.mainVersion = source.getMainVersion();
this.draftVersion = source.getDraftVersion();
this.contentHomes = source.getContentHomesAsMap() != null ? Maps.newTreeMap( source.getContentHomesAsMap() ) : null;
this.versions = source.getVersions() != null ? Lists.newArrayList( source.getVersions() ) : null;
this.relatedParents =
source.getRelatedParentContentVersions() != null ? Sets.newHashSet( source.getRelatedParentContentVersions() ) : null;
this.sectionContents = source.getSectionContents() != null ? Sets.newHashSet( source.getSectionContents() ) : null;
this.directMenuItemPlacements =
source.getDirectMenuItemPlacements() != null ? new TreeSet<MenuItemEntity>( source.getDirectMenuItemPlacements() ) : null;
if ( source.getContentAccessRights() != null )
{
TreeMap<GroupKey, ContentAccessEntity> contentAccessRightsCopy = Maps.newTreeMap( new GroupKeyComparator() );
contentAccessRightsCopy.putAll( source.contentAccessRights );
this.contentAccessRights = contentAccessRightsCopy;
}
}
public ContentKey getKey()
{
return key;
}
public boolean isDeleted()
{
return deleted != null && deleted != 0;
}
public Integer getDeleted()
{
return deleted;
}
public Integer getPriority()
{
return priority;
}
public Date getCreatedAt()
{
return createdAt;
}
public UserEntity getOwner()
{
return owner;
}
public Date getAvailableFrom()
{
return availableFrom;
}
public Date getAvailableTo()
{
return availableTo;
}
public UserEntity getAssignee()
{
return assignee;
}
public UserEntity getAssigner()
{
return assigner;
}
public Date getAssignmentDueDate()
{
return assignmentDueDate;
}
public boolean isAssignmentOverdue()
{
if ( assignmentDueDate == null )
{
return false;
}
DateTime dueDate = new DateTime( assignmentDueDate );
return dueDate.isBeforeNow();
}
public String getAssignmentDescription()
{
return assignmentDescription;
}
public CategoryEntity getCategory()
{
return category;
}
public ContentTypeEntity getContentType()
{
return category.getContentType();
}
public LanguageEntity getLanguage()
{
return language;
}
public ContentEntity getSource()
{
return source;
}
public ContentVersionEntity getMainVersion()
{
return mainVersion;
}
public boolean isAssigned()
{
return assignee != null;
}
public ContentVersionEntity getAssignedVersion()
{
if ( assignee == null )
{
return null;
}
if ( draftVersion != null )
{
return draftVersion;
}
return mainVersion;
}
public SortedMap<Integer, ContentHomeEntity> getContentHomesAsMap()
{
return contentHomes;
}
public Collection<ContentHomeEntity> getContentHomes()
{
return contentHomes.values();
}
public List<ContentVersionEntity> getVersions()
{
return versions;
}
public ContentVersionEntity getVersion( ContentVersionKey contentVersionKey )
{
for ( ContentVersionEntity version : versions )
{
if ( version.getKey().equals( contentVersionKey ) )
{
return version;
}
}
return null;
}
public int getVersionCount()
{
return versions.size();
}
public void addVersion( ContentVersionEntity version )
{
version.setContent( this );
versions.add( version );
}
public void removeVersion( ContentVersionEntity version )
{
versions.remove( version );
}
public Set<ContentVersionEntity> getRelatedParentContentVersions()
{
return relatedParents;
}
public SortedSet<MenuItemEntity> getDirectMenuItemPlacements()
{
return directMenuItemPlacements;
}
public void setKey( ContentKey key )
{
this.key = key;
}
public void setDeleted( boolean deleted )
{
if ( deleted )
{
this.deleted = 1;
}
else
{
this.deleted = 0;
}
}
public void setPriority( Integer priority )
{
this.priority = priority;
}
public void setCreatedAt( Date created )
{
this.createdAt = created;
}
public String getName()
{
return name;
}
public void setName( String name )
{
this.name = name;
}
public boolean setAvailableFrom( Date value )
{
if ( availableFrom == null && value == null )
{
return false;
}
long otherTime = value != null ? value.getTime() : -1;
long thisTime = availableFrom != null ? availableFrom.getTime() : -1;
if ( thisTime == otherTime )
{
return false;
}
this.availableFrom = value;
return true;
}
public boolean setAvailableTo( Date value )
{
if ( availableTo == null && value == null )
{
return false;
}
long otherTime = value != null ? value.getTime() : -1;
long thisTime = availableTo != null ? availableTo.getTime() : -1;
if ( thisTime == otherTime )
{
return false;
}
this.availableTo = value;
return true;
}
public void setAssigner( UserEntity assigner )
{
this.assigner = assigner;
}
public void setAssignee( UserEntity assignee )
{
this.assignee = assignee;
}
public boolean setAssignmentDueDate( Date value )
{
if ( assignmentDueDate == null && value == null )
{
return false;
}
long otherTime = value != null ? value.getTime() : -1;
long thisTime = assignmentDueDate != null ? assignmentDueDate.getTime() : -1;
if ( thisTime == otherTime )
{
return false;
}
this.assignmentDueDate = value;
return true;
}
public void setAssignmentDescription( String assignmentDescription )
{
this.assignmentDescription = assignmentDescription;
}
public void setOwner( UserEntity owner )
{
this.owner = owner;
}
public void setCategory( CategoryEntity category )
{
this.category = category;
}
public void setLanguage( LanguageEntity language )
{
this.language = language;
}
public void setSource( ContentEntity source )
{
this.source = source;
}
public void setMainVersion( ContentVersionEntity value )
{
this.mainVersion = value;
}
public void addContentHome( ContentHomeEntity contentHome )
{
Assert.notNull( contentHome );
Assert.notNull( contentHome.getSite() );
final SiteKey siteKey = contentHome.getSite().getKey();
contentHome.setKey( new ContentHomeKey( siteKey, this.getKey() ) );
contentHome.setContent( this );
contentHomes.put( siteKey.toInt(), contentHome );
}
public void addSectionContent( SectionContentEntity sectionContent )
{
sectionContent.setContent( this );
this.sectionContents.add( sectionContent );
}
public Set<SectionContentEntity> getSectionContents()
{
return sectionContents;
}
public void addContentAccessRights( Collection<ContentAccessEntity> values )
{
for ( ContentAccessEntity contentAccess : values )
{
contentAccess.setContent( this );
contentAccessRights.put( contentAccess.getGroup().getGroupKey(), contentAccess );
}
}
public void addContentAccessRight( ContentAccessEntity contentAccess )
{
contentAccess.setContent( this );
contentAccessRights.put( contentAccess.getGroup().getGroupKey(), contentAccess );
}
public boolean removeContentAccessRightByGroup( GroupKey groupKey )
{
Object removedObject = contentAccessRights.remove( groupKey );
return removedObject != null;
}
public void removeAllContentAccessRights()
{
contentAccessRights.clear();
}
public ContentAccessEntity getContentAccessRight( GroupKey groupKey )
{
return contentAccessRights.get( groupKey );
}
public Collection<ContentAccessEntity> getContentAccessRights()
{
return contentAccessRights.values();
}
public void setContentHomes( SortedMap<Integer, ContentHomeEntity> contentHomes )
{
this.contentHomes = contentHomes;
}
public void setSectionContents( Set<SectionContentEntity> sectionContents )
{
this.sectionContents = sectionContents;
}
public void setDirectMenuItemPlacements( SortedSet<MenuItemEntity> directMenuItemPlacements )
{
this.directMenuItemPlacements = directMenuItemPlacements;
}
public void addDirectMenuItemPlacement( MenuItemEntity menuItem )
{
directMenuItemPlacements.add( menuItem );
}
public boolean hasDirectMenuItemPlacements()
{
return !directMenuItemPlacements.isEmpty();
}
public boolean hasDraft()
{
return draftVersion != null;
}
public ContentVersionEntity getDraftVersion()
{
return draftVersion;
}
public void setDraftVersion( ContentVersionEntity draftVersion )
{
this.draftVersion = draftVersion;
}
public MenuItemEntity getFirstDirectPlacementOnMenuItem( SiteKey siteKey )
{
for ( MenuItemEntity menuItem : directMenuItemPlacements )
{
if ( menuItem.getSite().getKey().equals( siteKey ) )
{
return menuItem;
}
}
return null;
}
public boolean isOnline( DateTime date )
{
return isOnline( date.toDate() );
}
public boolean isOnline( Date date )
{
return !isDeleted() && isAvailableByDateTime( date ) && getMainVersion().isApproved();
}
private boolean isAvailableByDateTime( Date date )
{
if ( availableFrom == null )
{
return false;
}
if ( availableFrom.after( date ) )
{
return false;
}
if ( availableTo != null )
{
if ( date.after( availableTo ) || date.equals( availableTo ) )
{
return false;
}
}
return true;
}
public boolean hasHome( SiteKey siteKey )
{
return getContentHome( siteKey ) != null;
}
public ContentHomeEntity getContentHome( SiteKey siteKey )
{
return contentHomes.get( siteKey.toInt() );
}
public boolean hasAccessRightSet( final GroupKey group, final ContentAccessType type )
{
Preconditions.checkNotNull( group, "Given group cannot be null" );
ContentAccessEntity access = contentAccessRights.get( group );
if ( access == null )
{
return false;
}
switch ( type )
{
case READ:
return access.isReadAccess();
case UPDATE:
return access.isUpdateAccess();
case DELETE:
return access.isDeleteAccess();
default:
return false;
}
}
public boolean hasAccessRightSet( final GroupEntity group, final ContentAccessType type )
{
Preconditions.checkNotNull( group, "Given group cannot be null" );
return hasAccessRightSet( group.getGroupKey(), type );
}
public void accumulateAccess( ContentAccessRightsAccumulated accumulated, GroupEntity group )
{
ContentAccessEntity access = contentAccessRights.get( group.getGroupKey() );
if ( access != null )
{
accumulated.accumulate( access );
}
}
@Override
public boolean equals( Object o )
{
if ( this == o )
{
return true;
}
if ( !( o instanceof ContentEntity ) )
{
return false;
}
ContentEntity that = (ContentEntity) o;
if ( key != null ? !key.equals( that.getKey() ) : that.getKey() != null )
{
return false;
}
return true;
}
public int hashCode()
{
final int initialNonZeroOddNumber = 97;
final int multiplierNonZeroOddNumber = 71;
return new HashCodeBuilder( initialNonZeroOddNumber, multiplierNonZeroOddNumber ).append( key ).toHashCode();
}
public String toString()
{
StringBuffer s = new StringBuffer();
s.append( "key = " ).append( key );
return s.toString();
}
public boolean isActiviatedInSection( MenuItemEntity menuItem )
{
for ( SectionContentEntity sectionContent : getSectionContents() )
{
if ( menuItem.equals( sectionContent.getMenuItem() ) && sectionContent.isApproved() )
{
return true;
}
}
return false;
}
public ContentLocations getLocations( final ContentLocationSpecification spec )
{
ContentLocations contentLocations = new ContentLocations( this );
for ( MenuItemEntity menuItem : directMenuItemPlacements )
{
final boolean siteResrictionOK = spec.getSiteKey() == null || menuItem.getSite().getKey().equals( spec.getSiteKey() );
if ( siteResrictionOK )
{
contentLocations.addDirectMenuItemLocation( menuItem );
}
}
for ( SectionContentEntity sectionContent : sectionContents )
{
final MenuItemEntity menuItem = sectionContent.getMenuItem();
final boolean siteRestrictionOK = spec.getSiteKey() == null || menuItem.getSite().getKey().equals( spec.getSiteKey() );
final boolean activeInSectionRestrictionOK = sectionContent.isApproved() || spec.includeInactiveLocationsInSection();
if ( siteRestrictionOK && activeInSectionRestrictionOK )
{
contentLocations.addSectionMenuItemLocation( sectionContent );
}
}
for ( ContentHomeEntity contentHome : contentHomes.values() )
{
final MenuItemEntity contentHomeMenuItem = contentHome.getMenuItem();
if ( contentHomeMenuItem == null )
{
continue;
}
final boolean siteRestrictionOK =
spec.getSiteKey() == null || spec.getSiteKey().equals( contentHomeMenuItem.getSite().getKey() );
if ( siteRestrictionOK )
{
contentLocations.addSectionHomeLocation( contentHome );
}
}
contentLocations.resolveHomes();
return contentLocations;
}
/**
* @return the path (from archive top level) of this content.
*/
public String getPathAsString()
{
String categoryPath = getCategory().getPathAsString();
if ( categoryPath == null )
{
return null;
}
return categoryPath + "/" + getName();
}
public void addOwnerAccessRight()
{
if ( getOwner().isAnonymous() || getOwner().isRoot() )
{
return;
}
ContentAccessEntity contentAccess = new ContentAccessEntity();
contentAccess.setGroup( getOwner().getUserGroup() );
contentAccess.setReadAccess( true );
contentAccess.setUpdateAccess( true );
contentAccess.setDeleteAccess( true );
addContentAccessRight( contentAccess );
}
public Date getTimestamp()
{
return timestamp;
}
public void setTimestamp( Date timestamp )
{
this.timestamp = timestamp;
}
public void setTimestamp()
{
this.timestamp = Calendar.getInstance().getTime();
}
public SectionContentEntity removeSectionContent( MenuItemKey sectionKey )
{
if ( sectionContents != null && sectionContents.size() > 0 )
{
SectionContentEntity sectionContentToRemove = null;
for ( SectionContentEntity sectionContent : sectionContents )
{
if ( sectionContent.getMenuItem().getKey().equals( sectionKey ) )
{
sectionContentToRemove = sectionContent;
break;
}
}
if ( sectionContentToRemove == null )
{
return null;
}
else
{
sectionContents.remove( sectionContentToRemove );
return sectionContentToRemove;
}
}
return null;
}
public void removeContentHome( SiteKey siteKey )
{
contentHomes.remove( siteKey.toInt() );
}
}