/*
* 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.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.jdom.Document;
import com.google.common.base.Preconditions;
import com.google.common.collect.Sets;
import com.enonic.cms.framework.util.LazyInitializedJDOMDocument;
import com.enonic.cms.core.content.binary.BinaryDataEntity;
import com.enonic.cms.core.content.binary.BinaryDataKey;
import com.enonic.cms.core.content.binary.ContentBinaryDataEntity;
import com.enonic.cms.core.content.contentdata.ContentData;
import com.enonic.cms.core.content.contentdata.ContentDataParser;
import com.enonic.cms.core.content.contentdata.ContentDataXmlCreator;
import com.enonic.cms.core.content.contentdata.custom.TitleDataEntryNotFoundException;
import com.enonic.cms.core.content.contenttype.ContentTypeEntity;
import com.enonic.cms.core.security.user.UserEntity;
public class ContentVersionEntity
implements Serializable, Cloneable
{
public static final int STATE_PUBLISH_WAITING = 4;
public static final int STATE_PUBLISHED = 5;
public static final int STATE_PUBLISH_EXPIRED = 6;
private ContentVersionKey key;
private Integer status;
private String title;
private String changeComment;
private Date createdAt;
private Date modifiedAt;
private UserEntity modifiedBy;
private LazyInitializedJDOMDocument contentDataXml;
private transient Document contentDataXmlAsDocument;
private ContentEntity content;
private ContentVersionEntity snapshotSource;
private Set<ContentVersionEntity> snapshots = new LinkedHashSet<ContentVersionEntity>();
@SuppressWarnings({"JpaModelErrorInspection"})
private Set<ContentEntity> relatedChildren = new LinkedHashSet<ContentEntity>();
private Set<ContentBinaryDataEntity> contentBinaryData = new LinkedHashSet<ContentBinaryDataEntity>();
private transient ContentData contentData;
public ContentVersionEntity()
{
// Default constructor used by Hibernate.
}
public ContentVersionEntity( ContentVersionEntity source )
{
this();
this.key = source.getKey();
this.status = source.getStatus().getKey();
this.title = source.getTitle();
this.changeComment = source.getChangeComment();
this.createdAt = source.getCreatedAt();
this.modifiedAt = source.getModifiedAt();
this.modifiedBy = source.getModifiedBy() != null ? new UserEntity( source.getModifiedBy() ) : null;
this.contentDataXml =
source.getContentDataAsXmlString() != null ? new LazyInitializedJDOMDocument( source.getContentDataAsXmlString() ) : null;
this.content = source.getContent();
this.snapshotSource = source.getSnapshotSource();
this.snapshots = source.getSnapshots() != null ? Sets.newLinkedHashSet( source.getSnapshots() ) : null;
this.relatedChildren = source.getRelatedChildren() != null ? Sets.newLinkedHashSet( source.getRelatedChildren() ) : null;
this.contentBinaryData = source.getContentBinaryData() != null ? Sets.newLinkedHashSet( source.getContentBinaryData() ) : null;
}
public ContentVersionKey getKey()
{
return key;
}
public ContentStatus getStatus()
{
return ContentStatus.get( status );
}
public boolean hasStatus( ContentStatus value )
{
return status == value.getKey();
}
public String getStatusName()
{
if ( status == null )
{
return null;
}
return ContentStatus.get( status ).getName();
}
public boolean isDraft()
{
return status == ContentStatus.DRAFT.getKey();
}
public boolean isSnapshot()
{
return status == ContentStatus.SNAPSHOT.getKey();
}
public boolean isApproved()
{
return status == ContentStatus.APPROVED.getKey();
}
public boolean isArchived()
{
return status == ContentStatus.ARCHIVED.getKey();
}
public int getState( Date now )
{
int state;
if ( isApproved() && isMainVersion() )
{
Date from = content.getAvailableFrom();
Date to = content.getAvailableTo();
if ( from == null && to == null )
{
state = ContentStatus.APPROVED.getKey();
}
else if ( from == null )
{
if ( now.after( to ) || now.equals( to ) )
{
state = ContentVersionEntity.STATE_PUBLISH_EXPIRED;
}
else
{
state = ContentStatus.APPROVED.getKey();
}
}
else if ( from.after( now ) )
{
state = ContentVersionEntity.STATE_PUBLISH_WAITING;
}
else
{ // from.before(now) == true
if ( to == null || to.after( now ) )
{
state = ContentVersionEntity.STATE_PUBLISHED;
}
else
{
state = ContentVersionEntity.STATE_PUBLISH_EXPIRED;
}
}
}
else
{
state = status;
}
return state;
}
public String getTitle()
{
return title;
}
public String getChangeComment()
{
return changeComment;
}
public Date getCreatedAt()
{
return createdAt;
}
public Date getModifiedAt()
{
return modifiedAt;
}
public ContentEntity getContent()
{
return content;
}
public UserEntity getModifiedBy()
{
return modifiedBy;
}
public boolean hasRelatedChild( ContentEntity content )
{
return relatedChildren.contains( content );
}
public Set<ContentEntity> getRelatedChildren()
{
return relatedChildren;
}
public Collection<ContentEntity> getRelatedChildren( boolean includeDeleted )
{
if ( includeDeleted )
{
return relatedChildren;
}
List<ContentEntity> notDeletedChildren = new ArrayList<ContentEntity>();
for ( ContentEntity relatedChild : relatedChildren )
{
if ( !relatedChild.isDeleted() )
{
notDeletedChildren.add( relatedChild );
}
}
return notDeletedChildren;
}
public boolean hasContentBinaryData()
{
return !contentBinaryData.isEmpty();
}
public Set<ContentBinaryDataEntity> getContentBinaryData()
{
return contentBinaryData;
}
public Set<BinaryDataKey> getContentBinaryDataKeys()
{
Set<BinaryDataKey> keys = new HashSet<BinaryDataKey>();
for ( ContentBinaryDataEntity contentBinaryData : this.contentBinaryData )
{
keys.add( contentBinaryData.getBinaryData().getBinaryDataKey() );
}
return keys;
}
public void setKey( ContentVersionKey key )
{
this.key = key;
}
public void setStatus( ContentStatus status )
{
this.status = status.getKey();
}
public void setTitle( String title )
{
this.title = title;
}
public void setChangeComment( String changeComment )
{
this.changeComment = changeComment;
}
public void setCreatedAt( Date created )
{
this.createdAt = created;
}
public void setModifiedAt( Date value )
{
this.modifiedAt = value;
}
public void setContentDataXml( String value )
{
contentDataXml = new LazyInitializedJDOMDocument( value );
contentDataXmlAsDocument = null;
}
public String getContentDataAsXmlString()
{
if ( contentDataXml == null )
{
return null;
}
return contentDataXml.getDocumentAsString();
}
/**
* Returns always a new JDOM Document.
*
* @return
*/
public Document getContentDataAsJDomDocument()
{
if ( contentDataXml == null )
{
return null;
}
if ( contentDataXmlAsDocument == null )
{
contentDataXmlAsDocument = contentDataXml.getDocument();
}
return (Document) contentDataXmlAsDocument.clone();
}
public ContentData getContentData()
{
if ( contentDataXml == null )
{
return null;
}
if ( contentData == null )
{
final ContentTypeEntity conentType = getContent().getCategory().getContentType();
contentData = ContentDataParser.parse( getContentDataAsJDomDocument(), conentType, null );
}
return contentData;
}
public void setContentData( ContentData contentData )
{
if ( contentData == null )
{
throw new IllegalArgumentException( "contentData cannot be null" );
}
this.contentData = contentData;
try
{
this.title = this.contentData.getTitle();
}
catch ( TitleDataEntryNotFoundException e )
{
this.title = null;
}
setXmlDataFromContentData();
}
/**
* Updates the persisted field contentDataAsXml with from transient field contentData.
*/
public void setXmlDataFromContentData()
{
if ( contentData != null )
{
Document contentdataDoc = ContentDataXmlCreator.createContentDataDocument( contentData );
this.contentDataXml = LazyInitializedJDOMDocument.parse( contentdataDoc );
this.contentDataXmlAsDocument = null;
}
}
public void setContent( ContentEntity value )
{
this.content = value;
}
public void setModifiedBy( UserEntity value )
{
this.modifiedBy = value;
}
public void addRelatedChild( ContentEntity value )
{
relatedChildren.add( value );
}
public void removeRelatedChild( ContentEntity content )
{
relatedChildren.remove( content );
}
public void addContentBinaryData( ContentBinaryDataEntity contentBinaryData )
{
contentBinaryData.setContentVersion( this );
this.contentBinaryData.add( contentBinaryData );
}
public BinaryDataEntity getBinaryData( final String label )
{
ContentBinaryDataEntity contentBinaryData = getContentBinaryData( label );
if ( contentBinaryData == null )
{
return null;
}
return contentBinaryData.getBinaryData();
}
public BinaryDataEntity getOneAndOnlyBinaryData()
{
ContentBinaryDataEntity cbd = getOneAndOnlyContentBinaryData();
if ( cbd == null )
{
return null;
}
return cbd.getBinaryData();
}
public ContentBinaryDataEntity getOneAndOnlyContentBinaryData()
{
Set<ContentBinaryDataEntity> contentBinaryDataSet = getContentBinaryData();
Preconditions.checkArgument( contentBinaryDataSet.size() < 2,
"Expected not more than one content binary for this contentVersion: " + getKey() );
if ( contentBinaryDataSet.size() == 0 )
{
return null;
}
return contentBinaryDataSet.iterator().next();
}
public ContentBinaryDataEntity getContentBinaryData( final String label )
{
Preconditions.checkNotNull( label, "Given label cannot be null" );
for ( ContentBinaryDataEntity contentBinaryData : getContentBinaryData() )
{
if ( label.equals( contentBinaryData.getLabel() ) )
{
return contentBinaryData;
}
}
return null;
}
public BinaryDataEntity getBinaryData( final BinaryDataKey binaryDataKey )
{
ContentBinaryDataEntity contentBinaryData = getContentBinaryData( binaryDataKey );
if ( contentBinaryData == null )
{
return null;
}
return contentBinaryData.getBinaryData();
}
public ContentBinaryDataEntity getContentBinaryData( final BinaryDataKey binaryDataKey )
{
Preconditions.checkNotNull( binaryDataKey, "Given binaryDataKey cannot be null" );
for ( ContentBinaryDataEntity contentBinaryData : getContentBinaryData() )
{
if ( contentBinaryData.getBinaryData().getBinaryDataKey().equals( binaryDataKey ) )
{
return contentBinaryData;
}
}
return null;
}
public boolean isMainVersion()
{
final ContentVersionKey mainVersionKey = getContent().getMainVersion().getKey();
return mainVersionKey.equals( key );
}
@Override
public boolean equals( Object o )
{
if ( this == o )
{
return true;
}
if ( !( o instanceof ContentVersionEntity ) )
{
return false;
}
ContentVersionEntity that = (ContentVersionEntity) o;
if ( key != null ? !key.equals( that.getKey() ) : that.getKey() != null )
{
return false;
}
return true;
}
public int hashCode()
{
final int initialNonZeroOddNumber = 645;
final int multiplierNonZeroOddNumber = 235;
return new HashCodeBuilder( initialNonZeroOddNumber, multiplierNonZeroOddNumber ).append( key ).toHashCode();
}
public String toString()
{
StringBuffer b = new StringBuffer();
b.append( "key = " ).append( key ).append( ", name = '" ).append( title ).append( "'" );
return b.toString();
}
public boolean removeContentBinaryDataByBinaryDataKeys( final Set<BinaryDataKey> binaryDataToRemove )
{
boolean anyRemoved = false;
if ( binaryDataToRemove.size() == 0 )
{
return anyRemoved;
}
// First: find the content binary datas to remove...
List<ContentBinaryDataEntity> contentBinaryDatasToRemove = new ArrayList<ContentBinaryDataEntity>();
for ( ContentBinaryDataEntity contentBinaryData : this.contentBinaryData )
{
if ( binaryDataToRemove.contains( contentBinaryData.getBinaryData().getBinaryDataKey() ) )
{
contentBinaryDatasToRemove.add( contentBinaryData );
anyRemoved = true;
}
}
this.contentBinaryData.removeAll( contentBinaryDatasToRemove );
return anyRemoved;
}
public List<BinaryDataKey> removeContentBinaryData()
{
List<BinaryDataKey> removedBinaryDataKeys = new ArrayList<BinaryDataKey>();
for ( ContentBinaryDataEntity contentBinaryData : this.contentBinaryData )
{
removedBinaryDataKeys.add( contentBinaryData.getBinaryData().getBinaryDataKey() );
}
this.contentBinaryData.clear();
return removedBinaryDataKeys;
}
public ContentVersionEntity getSnapshotSource()
{
return snapshotSource;
}
public void setSnapshotSource( ContentVersionEntity snapshotSource )
{
this.snapshotSource = snapshotSource;
}
public Set<ContentVersionEntity> getSnapshots()
{
return snapshots;
}
public void addSnapshot( ContentVersionEntity snapshot )
{
snapshots.add( snapshot );
}
}