/* vim: set ts=2 et sw=2 cindent fo=qroca: */ package com.globant.katari.editablepages.domain; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; import javax.persistence.UniqueConstraint; import org.compass.annotations.Searchable; import org.compass.annotations.SearchableId; import org.compass.annotations.SearchableProperty; import org.apache.commons.lang.Validate; /** Defines a page that can be modified by a user. * * A page has a life cycle: once created, it starts its life as a dirty page * with no published content. Such a page is considered non-existent to users * without enough privileges. * * After the page is created, it must be published to be accessible by final * users. * * If a user modifies a page, the modified content is not yet accessible to the * final user until it is published. * * A page registers who was the last person to modify the page and at what time * it was last published. */ @Entity @Table(name = "pages", uniqueConstraints = { @UniqueConstraint(columnNames = { "site_name", "name" }) }) @Searchable public class Page { /** The length in characters of the page name. */ private static final int PAGE_NAME_LENGTH = 50; /** The length in characters of the page title. */ private static final int TITLE_LENGTH = 50; /** The length in characters of the creator's name. */ private static final int CREATOR_NAME_LENGTH = 50; /** The length in characters of the page content. */ private static final int CONTENT_LENGTH = 100000; /** The id of the page, 0 for a newly created page. */ @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "id", nullable = false) @SearchableId private long id = 0; /** The name of the site that the page belongs to. * * It is null only for a new page. */ @SuppressWarnings("unused") @Column(name = "site_name", nullable = false) @SearchableProperty private String siteName; /** The name of the page. * * The page name is used in a way analogous to a physical file. It is never * null. */ @Column(name = "name", nullable = false, unique = false, length = PAGE_NAME_LENGTH) @SearchableProperty private String name; /** The title of the page * * The title is inserted in the html title element. */ @Column(name = "title", nullable = false, length = TITLE_LENGTH) @SearchableProperty private String title; /** The content of the page. * * This is the content that is shown to the user. It is null if the page was * created and not yet published. */ @Column(name = "content", nullable = true, length = CONTENT_LENGTH) @SearchableProperty private String content = null; /** The unpublished content of the page (html code). */ @Column(name = "unpublished_content", nullable = true, length = CONTENT_LENGTH) private String unpublishedContent; /** The date that the page was last published. * * It is null for new pages not yet published. */ @Temporal(TemporalType.TIMESTAMP) @Column(name = "publication_date", nullable = true) private Date publicationDate = null; /** The name of the user that last modified the page. * * When the page is originally created, this is the user that created the * page. It is never null. */ @Column(name = "modifier", nullable = false, length = CREATOR_NAME_LENGTH) @SearchableProperty private String modifier; /** The default constructor to make hibernate happy. */ protected Page() { } /** A custom constructor. * * Builds a page with the most basic data it needs to have. The page starts * unpublished * * @param theName The page name. It cannot be null. * * @param theTitle The page title, shown in the html header. It cannot be * null. * * @param initialContent The page content, it cannot be null, it should be * html code. * * @param theCreator The page creator's name, he will be also the last * modifier of the page, it cannot be null. The user should exists */ public Page(final String theCreator, final String theName, final String theTitle, final String initialContent) { Validate.notNull(theCreator, "The page creator cannot be null"); Validate.notNull(theName, "The page name cannot be null"); Validate.notNull(theTitle, "The page title cannot be null"); Validate.notNull(initialContent, "The page content cannot be null"); name = theName; unpublishedContent = initialContent; title = theTitle; modifier = theCreator; } /** Modifies the page. * * @param user the name of the user who modifies the page, it cannot be null * * @param newName The new name of the page. It cannot be null. * * @param newTitle The new title for the page. It cannot be null. * * @param newContent The new content of the page. It cannot be null It * becomes available for view when published, previous content is saved and * shown until published. */ public void modify(final String user, final String newName, final String newTitle, final String newContent) { Validate.notNull(user, "The user who modifies the table cant be null"); Validate.notNull(newName, "The page name cannot be null"); Validate.notNull(newTitle, "The page title cannot be null"); Validate.notNull(newContent, "The page content cannot be null"); modifier = user; name = newName; title = newTitle; unpublishedContent = newContent; } /** Publishes the page, making the modified content available to the final * user. * * You can only publish dirty pages. */ public void publish() { Validate.notNull(unpublishedContent); content = unpublishedContent; unpublishedContent = null; publicationDate = new Date(); } /** Reverts the modification that are not published, if any. * * If the page has no unpublished content, this operation has no effect. */ public void revert() { unpublishedContent = null; } /** Returns if the page has some modification that can be published. * * @return false if it has not. */ public boolean isDirty() { return unpublishedContent != null; } /** Returns the id of the page. * * @return Returns the user id, 0 if the page was not persisted yet. */ public long getId() { return id; } /** Returns the page name. * * @return returns the name which is never null. */ public String getName() { return name; } /** Returns the page title. * * @return returns the title which is never null. */ public String getTitle() { return title; } /** Returns the content of the page. * * TODO Decide if returning null is the best option. An empty string is also * a good choice. * * @return The published content. If it is a new page that was never * published, this operation returns null. */ public String getContent() { return content; } /** Returns the content modified by an administrator that is not yet * published. * * @return The content that is not yet published. If it has not unpublished * content returns null. */ public String getUnpublishedContent() { return unpublishedContent; } /** Returns the date that the page was last published. * * @return The date of the last publication, null for a new page that was * never published. */ public Date getPublicationDate() { if (publicationDate == null) { return null; } else { return new Date(publicationDate.getTime()); } } /** Returns the name of the last person who modified the page. * * @return the last person who modified the page, it is null if the page is * not dirty. */ public String getModifier() { return modifier; } /** * Sets the name of the site that the page belongs to, it's only accessible by * the page repository. * * This is intended to be called from the page repository only. * * @param newSiteName it cannot be null. */ void setSiteName(final String newSiteName) { Validate.notNull(newSiteName); siteName = newSiteName; } }