Class ContentEntityObject

All Implemented Interfaces:
Searchable, Content, Addressable, ContentTypeAware, Versioned, RelatableEntity, EditableLabelable, Labelable, Serializable, Cloneable, Comparable<ContentEntityObject>
Direct Known Subclasses:
Comment, Draft, GlobalDescription, PersonalInformation, SpaceContentEntityObject

public abstract class ContentEntityObject extends AbstractLabelableEntityObject implements Searchable, Comparable<ContentEntityObject>, Addressable, Content, RelatableEntity
See Also:
  • Field Details

  • Constructor Details

    • ContentEntityObject

      protected ContentEntityObject()
  • Method Details

    • getType

      public abstract String getType()
      An easy name for the type of this content: makes it easy for things like the #contentLink macro to work out what to draw.

      This is a bit of a hack, but it saves heaps of code elsewhere, especially since we tend to get back these objects wrapped in all sorts of Hibernate CGLIB stuff.

      Specified by:
      getType in interface ContentTypeAware
      Returns:
      the content type
    • getTypeEnum

      public ContentTypeEnum getTypeEnum()
    • getIdAsString

      public String getIdAsString()
    • getDisplayTitle

      public String getDisplayTitle()
      Returns the display title. Some entities don't have titles for identification. For example, personal information objects use the user's fullname. Override this method to provide a custom title.
      Specified by:
      getDisplayTitle in interface Addressable
      Returns:
      the display title
    • getUrlPath

      public abstract String getUrlPath()
      Specified by:
      getUrlPath in interface Addressable
    • getAttachmentUrlPath

      public String getAttachmentUrlPath(Attachment attachment)
      Gets the path relative to Confluence's base URL to view the given attachment in the context of this content (for example, highlighted in the content's list of attachments). Generally you will want to call Attachment.getUrlPath() instead of this method: if we ever implement view pages for individual attachments, that's the method that will be changed to point to them.

      The default implementation just returns the view page for this content.

      Parameters:
      attachment - one of this content's attachments
      Returns:
      the path relative to the base url to view the attachment in the context of this content.
      Throws:
      IllegalArgumentException - if the attachment is not attached to this content
    • getTitle

      public String getTitle()
      Specified by:
      getTitle in interface EditableLabelable
    • setTitle

      public void setTitle(String title)
    • getLowerTitle

      public String getLowerTitle()
    • getDefaultBodyType

      public BodyType getDefaultBodyType()
    • getBodyContent

      public BodyContent getBodyContent()
      Gets the BodyContent object for this ContentEntityObject. Although it appears that there may be a number of BodyContent objects attached to a ContentEntityObject, only one is ever used. If there are none currently attached, a new BodyContent object is created and returned. Any values set on the returned BodyContent will not be saved unless a call is made to setBodyContent(com.atlassian.confluence.core.BodyContent). Null is never returned.

      This method should not normally be called directly unless, you need to be able to handle different body types. Use getBodyAsString() as you should normally be expecting only one type.

      Returns:
      the BodyContent.
      See Also:
    • getBodyContent

      public BodyContent getBodyContent(BodyType expectedBodyType)
      Gets the BodyContent object for this ContentEntityObject or throws an UnsupportedOperationException if its body type is not the same as the supplied expectedBodyType.

      This method should not normally be called directly unless, you need to be able to handle different body types. Use getBodyAsString() and getBodyAsString() as you should normally be expecting only one type.

      Parameters:
      expectedBodyType - that can be handled by the caller.
      Returns:
      the BodyContent.
      Throws:
      UnsupportedOperationException - if the BodyType of the content is not the expectedBodyType.
      See Also:
    • setBodyContent

      public void setBodyContent(BodyContent bodyContent)
      Sets the BodyContent object for this ContentEntityObject.

      This method should not normally be called directly unless, you need to be able to handle different body types. Use setBodyAsString(java.lang.String) as you should normally be expecting only one type.

      Parameters:
      bodyContent - to be set. If the supplied bodyContent or its body are null, the list of body contents are cleared.
    • getBodyAsString

      public String getBodyAsString()
      Convenience method that returns the String representation of the content.
      Returns:
      the content.
      Throws:
      UnsupportedOperationException - if the BodyType of the content is not the normal type (by default BodyType#XHTML) used by this ContentEntityObject.
    • setBodyAsString

      public void setBodyAsString(String content)
      Convenience method that sets the content of this ContentEntityObject.
      Parameters:
      content - the String representation of the content.
      Throws:
      UnsupportedOperationException - if the BodyType of the content is not the normal type (by default BodyType#XHTML) used by this ContentEntityObject.
    • getBodyContents

      public List<BodyContent> getBodyContents()
    • setBodyContents

      public void setBodyContents(List<BodyContent> bodyContents)
    • getOutgoingLinks

      public List<OutgoingLink> getOutgoingLinks()
      An outgoing link is a link on this page to another confluence page.
      It could also link to a website URL
      These links are contained in the page content
      They are refreshed each time the page is updated (LinkManager.updateOutgoingLinks())
      Returns:
      List of OutgoingLinks
    • setOutgoingLinks

      public void setOutgoingLinks(List<OutgoingLink> outgoingLinks)
    • addOutgoingLink

      public void addOutgoingLink(OutgoingLink link)
    • removeOutgoingLink

      public void removeOutgoingLink(OutgoingLink link)
    • setOriginalVersion

      public void setOriginalVersion(Versioned originalVersion)
      Description copied from interface: Versioned
      Set the current version of this object. After this method is called, this object will become an historical version of the object passed in.
      Specified by:
      setOriginalVersion in interface Versioned
      Overrides:
      setOriginalVersion in class AbstractVersionedEntityObject
      Parameters:
      originalVersion - the current version of this object.
    • convertToHistoricalVersion

      public void convertToHistoricalVersion()
      Description copied from interface: Versioned
      Remove all data from the object that does not need to be saved by historical versions. For versioned objects that are persisted, this includes removing associations with other persisted objects that may otherwise cause us to break the expected arity of the database relations.

      When using Hibernate to persist versioned objects, take special care to null any field that might contain a Hibernate-persisted collection, as Hibernate does not allow two different persistent objects to refer to the same persisted collection at the same time.

      Specified by:
      convertToHistoricalVersion in interface Versioned
      Overrides:
      convertToHistoricalVersion in class AbstractVersionedEntityObject
    • applyChildVersioningPolicy

      public void applyChildVersioningPolicy(@Nullable Versioned versionToPromote, Consumer<ContentEntityObject> dao)
      Description copied from interface: Versioned
      If Versioned.getVersionChildPolicy(com.atlassian.confluence.api.model.content.ContentType) specifies so, moves content from versionToPromote to this Versioned instance or makes no change.
      Specified by:
      applyChildVersioningPolicy in interface Versioned
      Parameters:
      versionToPromote - the new version of the current instance that we're getting the children from
      dao - onRemove used to delete dangling contained content
    • equals

      public boolean equals(Object o)
      Overrides:
      equals in class com.atlassian.core.bean.EntityObject
    • hashCode

      public int hashCode()
      Overrides:
      hashCode in class com.atlassian.core.bean.EntityObject
    • toString

      public String toString()
      Overrides:
      toString in class Object
    • getNameForComparison

      public abstract String getNameForComparison()
      Subclasses should implement this method, giving a String back so that the content can be alphabetically sorted in a mixed-type list of content-entities.
    • compareTo

      public final int compareTo(ContentEntityObject otherEntity)
      Content entities are naturally ordered alphabetically by "comparison name", which depends on the entity (it's the title for pages, the parent page title for comments, etc.).

      If the comparison names are identical, we fall back on creation dates. This ensures, for example, that comments are always listed after the pages they are contained in, and in posting order.

      Note also: comparison does NOT agree with equals(). This makes using content entities within sets a little dangerous, but the chances of two things with the exact same name being created on exactly the same millisecond is probably pretty low.

      Specified by:
      compareTo in interface Comparable<ContentEntityObject>
    • getSearchableDependants

      public Collection<Searchable> getSearchableDependants()
      Description copied from interface: Searchable
      When we un-index something (say, a page), we also need to un-index everything contained within that page (comments, attachments), because presumably they're all about to go away.
      Specified by:
      getSearchableDependants in interface Searchable
    • toPageContext

      public final PageContext toPageContext()
      When the content is rendered, what context is it being rendered in?
    • isIndexable

      public boolean isIndexable()
      Content entity objects that are historical versions should not be indexed.
      Specified by:
      isIndexable in interface Searchable
    • getPermissions

      @Deprecated public List<ContentPermission> getPermissions()
      Deprecated.

      Get all the permissions that apply to this content. Please do not modify the contents of this list!

      Returns:
      a list of all the permissions that apply to this content.
    • getContentPermission

      @Deprecated public ContentPermission getContentPermission(String permissionType)
      Deprecated.
      since 2.6 - use getContentPermissionSet
      Gives back the first content permission of a specific type. Returns only the permission if it is set on this object and not inherited. Returns null if no permission can't be found.

      Synchronized, as otherwise it was creating timing issues during the multi-threaded re-indexing.

      Returns:
      ContentPermission
    • sharedAccessAllowed

      @Deprecated public boolean sharedAccessAllowed(String shareId)
      Deprecated.
      since 5.10
      Checks if this draft can be accessed by users other than the creator (shared access)

      IMPORTANT NOTE: if shared access is disallowed it prevails over permissions (only creator has access), BUT if it is allowed normal permissions still need to be checked

      Drafts for existing objects are considered automatically shared according to the permissions set, but drafts for new objects are considered private, so if a user if trying to access one of them it should be verified that is doing so with the proper share id in addition to permissions.

      Parameters:
      shareId - Optional. Used to check for access if needed
      Returns:
      true if this draft can be accessed given a share id, false otherwise
      See Also:
    • getContentStatusObject

      public ContentStatus getContentStatusObject()
      Get the api layer enum for content status, distinguishing CURRENT/HISTORICAL/DRAFT/TRASHED.

      Important: this has different semantics from the hibernate field getContentStatus(), because it takes into account historical status, and uses different strings for some values.

      Returns:
      the API ContentStatus for this content, distinguishing CURRENT/HISTORICAL/DRAFT/TRASHED
      See Also:
    • getContentStatus

      public String getContentStatus()
      Get the hibernate field for content status, distinguishing only draft/deleted/current status.

      Important: this is not the same as the string value of the api getContentStatusObject(), because that one takes into account historical status, and uses different strings for some values.

      This method does NOT distinguish current and historical versions. Both will return "current". See AbstractVersionedEntityObject.isLatestVersion() to distinguish them.

      Returns:
      the hibernate field value, distinguishing only CURRENT, DRAFT, DELETED.
      See Also:
    • setContentStatus

      public void setContentStatus(String contentStatus)
      Set the hibernate field for content status, distinguishing only draft/deleted/current status.

      Important: this is not the same as the string value of the api getContentStatusObject(), because that one takes into account historical status, and uses different strings for some values.

      This method does NOT distinguish current and historical versions. Both use "current". See AbstractVersionedEntityObject.isLatestVersion() to distinguish them.

      Parameters:
      contentStatus - the hibernate field value, CURRENT, DRAFT, DELETED.
      See Also:
    • isCurrent

      public boolean isCurrent()
      Does this content have "current" status? (non-trashed and non-draft)

      This method does NOT distinguish current and historical versions. Both will return true. See AbstractVersionedEntityObject.isLatestVersion() to distinguish them.

      Returns:
      true if the content is live, i.e. not trashed and not a draft
      See Also:
    • isDeleted

      public boolean isDeleted()
    • isDraft

      public boolean isDraft()
    • sharedAccessAllowed

      public boolean sharedAccessAllowed(com.atlassian.user.User user)
      Checks if this draft can be accessed by users other than the creator (shared access)

      IMPORTANT NOTE: if shared access is disallowed it prevails over permissions (only creator has access), BUT if it is allowed normal permissions still need to be checked

      Drafts for existing objects are considered automatically shared according to the permissions set, but drafts that have never been published are considered private even without permissions set, so if a user if trying to access one of them it should be verified that is doing so with the proper share id in addition to permissions.

      Parameters:
      user - User to check
      Returns:
      true if this draft can be accessed given a share id, false otherwise
      See Also:
    • getShareId

      public String getShareId()
      See Also:
    • setShareId

      public void setShareId(String shareId)
      See Also:
    • getSynchronyRevision

      public String getSynchronyRevision()
      See Also:
    • setSynchronyRevision

      public void setSynchronyRevision(String synchronyRevision)
      See Also:
    • getSynchronyRevisionSource

      public String getSynchronyRevisionSource()
      See Also:
    • getTrashDate

      public Optional<Instant> getTrashDate()
      Get trash date if this CEO has been added to the trash since Confluence 7.14. For generic cases, use TrashManagerInternal#findTrashDate
      Returns:
      when this content entity was added to the trash or Optional.empty() if it was trashed before 7.14
      Since:
      7.14
    • setSynchronyRevisionSource

      public void setSynchronyRevisionSource(String synchronyRevisionSource)
      See Also:
    • getCollaborativeEditingUuid

      public String getCollaborativeEditingUuid()
      See Also:
    • setCollaborativeEditingUuid

      public void setCollaborativeEditingUuid(String uuid)
      See Also:
    • isUnpublished

      public boolean isUnpublished()
    • wasCreatedBy

      public boolean wasCreatedBy(com.atlassian.user.User user)
    • trash

      public void trash()
      places content in trash can
    • trash

      protected void trash(long trashTimestamp)
    • trashDependents

      protected void trashDependents()
    • restore

      public void restore()
      restores content from the trash
    • restoreDependents

      protected void restoreDependents()
    • getAttachments

      public List<Attachment> getAttachments()

      Don't use it directly, use AttachmentManager.getAttachments(page) instead.

      This also includes trashed items.

    • getLatestVersionsOfAttachments

      @Deprecated public List<Attachment> getLatestVersionsOfAttachments()
      Deprecated.
      Since 6.13. use AttachmentManager.getLatestVersionsOfAttachments(page) instead.
    • setAttachments

      public void setAttachments(List<Attachment> attachments)
    • addAttachment

      public void addAttachment(Attachment attachment)
    • removeAttachment

      public void removeAttachment(Attachment attachment)
    • getBodyAsStringWithoutMarkup

      public String getBodyAsStringWithoutMarkup()
    • getExcerpt

      public String getExcerpt()
    • getAttachmentsUrlPath

      public String getAttachmentsUrlPath()
    • getAttachmentNamed

      public Attachment getAttachmentNamed(String fileName)
    • getVersionComment

      public String getVersionComment()
    • setVersionComment

      public void setVersionComment(String versionComment)
    • isVersionCommentAvailable

      public boolean isVersionCommentAvailable()
    • clone

      public Object clone()
      Overrides:
      clone in class AbstractLabelableEntityObject
    • getRenderedVersionComment

      public String getRenderedVersionComment()
    • getContentPermissionSet

      public ContentPermissionSet getContentPermissionSet(String type)
      Note, this method does not return ContentPermissions inherited from the Content's ancestry.
      Returns:
      a set containing ContentPermissions of this type, or null if there are no content permissions explicitly set on this ContentEntityObject for the type.
    • hasPermissions

      public boolean hasPermissions(String type)
      Returns:
      true if this content entity object contains any ContentPermissions of the type specified
    • hasContentPermissions

      public boolean hasContentPermissions()
    • addPermission

      public void addPermission(ContentPermission permission)
      Adds a ContentPermission. Do not add them manually via ContentPermissionSet.addContentPermission(ContentPermission). If possible use ContentPermissionManager.addContentPermission(com.atlassian.confluence.security.ContentPermission, ContentEntityObject) instead. Also note that as of Confluence 2.4 although methods have been added to facilitate having multiple ContentPermissions per page, Confluence does not yet properly support them (eg users permitted by them will not see the data in their searches)
    • removeContentPermissionSet

      public void removeContentPermissionSet(ContentPermissionSet set)
      This method removes the given ContentPermissionSet from this CEO and disconnects the set from its owner. This method should only be called by the DefaultContentPermissionManager. Note that as of Confluence 2.4 although methods have been added to facilitate having multiple ContentPermissions per page, Confluence does not yet properly support them (eg users permitted by them will not see the data in their searches)
      See Also:
    • getComments

      public List<Comment> getComments()
    • setComments

      public void setComments(List<Comment> comments)
    • addComment

      public void addComment(Comment comment)
    • removeComment

      public void removeComment(Comment comment)
    • getCustomContent

      public List<CustomContentEntityObject> getCustomContent()
      Returns:
      all custom content that is a child of this CEO.
      Since:
      7.16.3
    • addCustomContent

      public void addCustomContent(CustomContentEntityObject customContentEntityObject)
    • removeCustomContent

      public void removeCustomContent(CustomContentEntityObject customContentEntityObject)
    • getEntity

      public ContentEntityObject getEntity()
      Description copied from interface: Content
      Gets the ContentEntityObject that backs this piece of content.
      Specified by:
      getEntity in interface Content
      Returns:
      the persistent object behind this content
    • ensureAttachmentBelongsToContent

      @EnsuresNonNullIf(expression="attachment.getContainer()", result=true) protected void ensureAttachmentBelongsToContent(Attachment attachment)
    • getContentId

      public ContentId getContentId()
      Returns the ContentId for this entity object, if it implements ContentConvertible.

      Subclasses implementing ContentConvertible must override this method.

      Returns:
      the ContentId representation of this object's id
      Throws:
      UnsupportedOperationException - if the instance doesn't implement ContentConvertible
    • getSelector

      public ContentSelector getSelector()
      Returns:
      the ContentSelector for this entity, which will always include the id of the latest version, and the version number for this version of the entity.
    • getProperties

      public ContentProperties getProperties()
      Returns:
      the content properties associated with this entity
    • getContainerContent

      protected @Nullable ContentEntityObject getContainerContent()
      Implementing classes wanting to be Contained in another CEO should implement the Contained interface and delegate to this method
      Returns:
      the CEO that contains this one
    • setContainerContent

      protected void setContainerContent(@Nullable ContentEntityObject container)
    • replaceContentProperties

      protected void replaceContentProperties(ContentProperties propertiesToClone)
      Clones the supplied properties and sets these as the properties of the current ContentEntityObject.

      This method should be used instead of directly modifying the contentProperties field, to avoid swapping collections that have Hibernate associations. Doing so would result in the following error: You may not dereference a collection with cascade="all-delete-orphan".

    • setContentPropertiesFrom

      public void setContentPropertiesFrom(ContentEntityObject ceo)
      Initialises the ContentProperties of this ContentEntityObject by performing a deep clone of the ContentEntityObject object's properties.
    • getOriginalVersionId

      public Long getOriginalVersionId()
    • setOriginalVersionId

      protected void setOriginalVersionId(@Nullable Long originalVersionId)
      For Hibernate
    • getLatestVersionId

      public long getLatestVersionId()
    • getAttachmentManager

      protected AttachmentManager getAttachmentManager()