Optimizations for the models processing content items.
parent
65d53e9992
commit
661c70073f
|
|
@ -4,21 +4,33 @@
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="bg-light mb-4 rounded-3">
|
<div class="bg-light mb-4 rounded-3">
|
||||||
<div class="container-fluid py-5">
|
<div class="container-fluid py-5">
|
||||||
<h1 class="display-5 fw-bold">
|
<#if CmsPagesCategorizedItemModel.itemAvailable>
|
||||||
LibreCMS
|
<h1 class="display-5 fw-bold">
|
||||||
</h1>
|
${CmsPagesCategorizedItemModel.title}
|
||||||
<p>
|
</h1>
|
||||||
No index item has been defined.
|
<p>
|
||||||
</p>
|
${CmsPagesCategorizedItemModel.description}
|
||||||
<a class="btn btn-primary btn-lg"
|
</p>
|
||||||
href="https://www.libreccm.org"
|
<a class="btn btn-primary btn-lg"
|
||||||
type="button">
|
href="#">
|
||||||
Find out more
|
Find out more
|
||||||
</a>
|
</a>
|
||||||
|
<#else>
|
||||||
|
<h1 class="display-5 fw-bold">
|
||||||
|
LibreCMS
|
||||||
|
</h1>
|
||||||
|
<p>
|
||||||
|
No index item has been defined.
|
||||||
|
</p>
|
||||||
|
<a class="btn btn-primary btn-lg"
|
||||||
|
href="https://www.libreccm.org">
|
||||||
|
Find out more
|
||||||
|
</a>
|
||||||
|
</#if>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<#if CmsPagesCategorizedItemModel.contentItem??>
|
<#if CmsPagesCategorizedItemModel.itemAvailable>
|
||||||
Category has an index item
|
Category has an index item
|
||||||
<#else>
|
<#else>
|
||||||
Category has no index item
|
Category has no index item
|
||||||
|
|
@ -34,6 +46,39 @@
|
||||||
<dt>view</dt>
|
<dt>view</dt>
|
||||||
<dd>${view!""}</dd>
|
<dd>${view!""}</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
|
<h2>From <code>ArticleModel</code></h2>
|
||||||
|
<dl>
|
||||||
|
<dt>Title</dt>
|
||||||
|
<dd>${CmsPagesArticleModel.title}</dd>
|
||||||
|
<dt>Description</dt>
|
||||||
|
<dd>${CmsPagesArticleModel.description}</dd>
|
||||||
|
<dt>Text</dt>
|
||||||
|
<dd>${CmsPagesArticleModel.text}</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
<h2>Item List</h2>
|
||||||
|
<p>Item List size: ${CmsPagesItemListModel.listSize}</p>
|
||||||
|
<ul>
|
||||||
|
<#list CmsPagesItemListModel.items as item>
|
||||||
|
<li>
|
||||||
|
<dl>
|
||||||
|
<dt>UUID</dt>
|
||||||
|
<dd>${item.uuid}</dd>
|
||||||
|
<dt>displayName</dt>
|
||||||
|
<dd>${item.displayName}</dd>
|
||||||
|
<dt>Name</dt>
|
||||||
|
<dd>${item.name}</dd>
|
||||||
|
<dt>Title</dt>
|
||||||
|
<dd>${item.title}</dd>
|
||||||
|
<dt>description</dt>
|
||||||
|
<dd>${item.description}</dd>
|
||||||
|
<dt>Type</dt>
|
||||||
|
<dd>${item.type}</dd>
|
||||||
|
</dl>
|
||||||
|
</li>
|
||||||
|
</#list>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</@main.librecms>
|
</@main.librecms>
|
||||||
|
|
@ -28,8 +28,6 @@ import javax.enterprise.context.RequestScoped;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.transaction.Transactional;
|
import javax.transaction.Transactional;
|
||||||
import javax.ws.rs.WebApplicationException;
|
|
||||||
import javax.ws.rs.core.Response;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Model for getting the special properties of an {@link Article}. For general
|
* Model for getting the special properties of an {@link Article}. For general
|
||||||
|
|
@ -39,7 +37,7 @@ import javax.ws.rs.core.Response;
|
||||||
*/
|
*/
|
||||||
@RequestScoped
|
@RequestScoped
|
||||||
@Named("CmsPagesArticleModel")
|
@Named("CmsPagesArticleModel")
|
||||||
public class ArticleModel {
|
public class ArticleModel implements ProcessesContentItem {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ContentItemModel contentItemModel;
|
private ContentItemModel contentItemModel;
|
||||||
|
|
@ -47,41 +45,46 @@ public class ArticleModel {
|
||||||
@Inject
|
@Inject
|
||||||
private GlobalizationHelper globalizationHelper;
|
private GlobalizationHelper globalizationHelper;
|
||||||
|
|
||||||
|
private boolean initialized;
|
||||||
|
|
||||||
private String title;
|
private String title;
|
||||||
|
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
private String text;
|
private String text;
|
||||||
|
|
||||||
|
public ArticleModel() {
|
||||||
|
initialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
if (title == null) {
|
contentItemModel.init();
|
||||||
init();
|
|
||||||
}
|
|
||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
if (description == null) {
|
contentItemModel.init();
|
||||||
init();
|
|
||||||
}
|
|
||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getText() {
|
public String getText() {
|
||||||
if (text == null) {
|
contentItemModel.init();
|
||||||
init();
|
|
||||||
}
|
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
protected void init() {
|
@Override
|
||||||
final ContentItem contentItem = contentItemModel
|
public void init(final ContentItem contentItem) {
|
||||||
.retrieveContentItem()
|
if (initialized) {
|
||||||
.orElse(null);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (contentItem instanceof Article) {
|
if (contentItem instanceof Article) {
|
||||||
final Article article = (Article) contentItem;
|
final Article article = (Article) contentItem;
|
||||||
|
|
||||||
|
|
@ -97,15 +100,8 @@ public class ArticleModel {
|
||||||
.ofNullable(article.getText())
|
.ofNullable(article.getText())
|
||||||
.map(globalizationHelper::getValueFromLocalizedString)
|
.map(globalizationHelper::getValueFromLocalizedString)
|
||||||
.orElse("");
|
.orElse("");
|
||||||
} else {
|
}
|
||||||
throw new WebApplicationException(
|
initialized = true;
|
||||||
"Current content item is not an article.",
|
|
||||||
Response
|
|
||||||
.status(Response.Status.INTERNAL_SERVER_ERROR)
|
|
||||||
.entity("Current content item is not an article.")
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,24 +18,24 @@
|
||||||
*/
|
*/
|
||||||
package org.librecms.pages.models;
|
package org.librecms.pages.models;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.libreccm.categorization.CategoryManager;
|
|
||||||
import org.libreccm.categorization.CategoryRepository;
|
import org.libreccm.categorization.CategoryRepository;
|
||||||
|
import org.libreccm.core.CcmObject;
|
||||||
import org.libreccm.l10n.GlobalizationHelper;
|
import org.libreccm.l10n.GlobalizationHelper;
|
||||||
import org.librecms.contentsection.ContentItem;
|
import org.librecms.contentsection.ContentItem;
|
||||||
import org.librecms.contentsection.ContentItemVersion;
|
import org.librecms.contentsection.ContentItemVersion;
|
||||||
|
import org.librecms.pages.PagesController;
|
||||||
import org.librecms.pages.PagesRouter;
|
import org.librecms.pages.PagesRouter;
|
||||||
import org.librecms.pages.PagesService;
|
import org.librecms.pages.PagesService;
|
||||||
|
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import javax.enterprise.context.RequestScoped;
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.enterprise.inject.Instance;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
import javax.transaction.Transactional;
|
import javax.transaction.Transactional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -50,162 +50,348 @@ import javax.transaction.Transactional;
|
||||||
@Named("CmsPagesCategorizedItemModel")
|
@Named("CmsPagesCategorizedItemModel")
|
||||||
public class ContentItemModel {
|
public class ContentItemModel {
|
||||||
|
|
||||||
private static final Logger LOGGER = LogManager.getLogger(
|
/**
|
||||||
ContentItemModel.class
|
* Category repository used to retrieve the current category.
|
||||||
);
|
*/
|
||||||
|
|
||||||
@Inject
|
|
||||||
private CategoryManager categoryManager;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private CategoryRepository categoryRepository;
|
private CategoryRepository categoryRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Category model used to get the curretn category.
|
||||||
|
*/
|
||||||
@Inject
|
@Inject
|
||||||
private CategoryModel categoryModel;
|
private CategoryModel categoryModel;
|
||||||
|
|
||||||
@Inject
|
/**
|
||||||
private EntityManager entityManager;
|
* Utility for globalization stuff.
|
||||||
|
*/
|
||||||
@Inject
|
@Inject
|
||||||
private GlobalizationHelper globalizationHelper;
|
private GlobalizationHelper globalizationHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides some utility methods.
|
||||||
|
*/
|
||||||
@Inject
|
@Inject
|
||||||
private PagesService pagesService;
|
private PagesService pagesService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All instances of implementations of the {@link ProcessesContentItem}
|
||||||
|
* interface.
|
||||||
|
*/
|
||||||
|
@Inject
|
||||||
|
private Instance<ProcessesContentItem> contentItemProcessingModels;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link DateTimeFormatter} instance for converting dates and times to an
|
||||||
|
* ISO 8601 date/time string.
|
||||||
|
*/
|
||||||
private final DateTimeFormatter dateTimeFormatter
|
private final DateTimeFormatter dateTimeFormatter
|
||||||
= DateTimeFormatter.ISO_DATE_TIME.withZone(ZoneId.systemDefault());
|
= DateTimeFormatter.ISO_DATE_TIME.withZone(ZoneId.systemDefault());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the item to be shown.
|
||||||
|
*/
|
||||||
private String itemName;
|
private String itemName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The version of the item to be shown.
|
||||||
|
*/
|
||||||
private ContentItemVersion itemVersion;
|
private ContentItemVersion itemVersion;
|
||||||
|
|
||||||
// private Optional<ContentItem> contentItem;
|
/**
|
||||||
|
* Data of the current content item, already prepared for retrieving the
|
||||||
|
* data from a MVC template. If no item with the {@link #itemName} provided
|
||||||
|
* by the {@link PagesController} is present in the category, the
|
||||||
|
* {@link Optional} will be empty.
|
||||||
|
*/
|
||||||
private Optional<ContentItemModelData> contentItem;
|
private Optional<ContentItemModelData> contentItem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the item name provided by the {@link PagesController}.
|
||||||
|
*
|
||||||
|
* @return The item name provided by the {@link PagesController}.
|
||||||
|
*/
|
||||||
public String getItemName() {
|
public String getItemName() {
|
||||||
return itemName;
|
return itemName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used by the {@link PagesController} to set the name of the requested
|
||||||
|
* content item. May be used by other controllers.
|
||||||
|
*
|
||||||
|
* @param itemName The name of the requested content item.
|
||||||
|
*/
|
||||||
public void setItemName(final String itemName) {
|
public void setItemName(final String itemName) {
|
||||||
this.itemName = itemName;
|
this.itemName = itemName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The requested version of the content item.
|
||||||
|
*
|
||||||
|
* @return The requested version of the content item.
|
||||||
|
*/
|
||||||
public ContentItemVersion getItemVersion() {
|
public ContentItemVersion getItemVersion() {
|
||||||
return itemVersion;
|
return itemVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used by controllers, for example the {@link PagesController} to set the
|
||||||
|
* requested version of the content item.
|
||||||
|
*
|
||||||
|
* @param itemVersion The requested version of the content item.
|
||||||
|
*/
|
||||||
public void setItemVersion(final ContentItemVersion itemVersion) {
|
public void setItemVersion(final ContentItemVersion itemVersion) {
|
||||||
this.itemVersion = itemVersion;
|
this.itemVersion = itemVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A convient getter for checking if a content item is available from a
|
||||||
|
* template.
|
||||||
|
*
|
||||||
|
* @return {@code true} if an item is available, {@code false} if not.
|
||||||
|
*/
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public boolean isItemAvailable() {
|
public boolean isItemAvailable() {
|
||||||
return getOrRetrieveContentItem().isPresent();
|
init();
|
||||||
}
|
return contentItem.isPresent();
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
|
||||||
public long getObjectId() {
|
|
||||||
return getOrRetrieveContentItem()
|
|
||||||
.map(ContentItemModelData::getObjectId)
|
|
||||||
.orElse(0L);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@code objectId)} (see {@link CcmObject#objectId} of the current
|
||||||
|
* item.
|
||||||
|
*
|
||||||
|
* @return The {@code objectId} of the current item if there is an item or
|
||||||
|
* {@code -1L} if there is no item.
|
||||||
|
*/
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public long getObjectId() {
|
||||||
|
init();
|
||||||
|
return contentItem
|
||||||
|
.map(ContentItemModelData::getObjectId)
|
||||||
|
.orElse(-1L);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the UUID of the current item (see {@link CcmObject#uuid}.
|
||||||
|
*
|
||||||
|
* @return The UUID of the current item if there is an item, an empty string
|
||||||
|
* if there is not item.
|
||||||
|
*/
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getUuid() {
|
public String getUuid() {
|
||||||
return getOrRetrieveContentItem()
|
init();
|
||||||
|
return contentItem
|
||||||
.map(ContentItemModelData::getUuid)
|
.map(ContentItemModelData::getUuid)
|
||||||
.orElse("");
|
.orElse("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the display name of the current item (see
|
||||||
|
* {@link CcmObject#displayName}.
|
||||||
|
*
|
||||||
|
* @return The display name of the current item, or an empty string if there
|
||||||
|
* is not current item.
|
||||||
|
*/
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getDisplayName() {
|
public String getDisplayName() {
|
||||||
return getOrRetrieveContentItem()
|
init();
|
||||||
|
return contentItem
|
||||||
.map(ContentItemModelData::getDisplayName)
|
.map(ContentItemModelData::getDisplayName)
|
||||||
.orElse("");
|
.orElse("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the item UUID of the current item (see {@link ContentItem#itemUuid}.
|
||||||
|
*
|
||||||
|
* @return The item UUID of the current item, or an empty string if the is
|
||||||
|
* no current item.
|
||||||
|
*/
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getItemUuid() {
|
public String getItemUuid() {
|
||||||
return getOrRetrieveContentItem()
|
init();
|
||||||
|
return contentItem
|
||||||
.map(ContentItemModelData::getItemUuid)
|
.map(ContentItemModelData::getItemUuid)
|
||||||
.orElse("");
|
.orElse("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the name of the current item {@link ContentItem#name}) for the
|
||||||
|
* current language (see {@link GlobalizationHelper#getNegotiatedLocale()}).
|
||||||
|
*
|
||||||
|
* @return The name of the the current item for the current language, or an
|
||||||
|
* empty string if there is no item.
|
||||||
|
*/
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return getOrRetrieveContentItem()
|
init();
|
||||||
|
return contentItem
|
||||||
.map(ContentItemModelData::getName)
|
.map(ContentItemModelData::getName)
|
||||||
.orElse("");
|
.orElse("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the title of the current item (see {@link ContentItem#title} for the
|
||||||
|
* current language (see {@link GlobalizationHelper#getNegotiatedLocale()}).
|
||||||
|
*
|
||||||
|
* @return The title of the current item for the current language, or an
|
||||||
|
* empty string if there is no item.
|
||||||
|
*/
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
return getOrRetrieveContentItem()
|
init();
|
||||||
|
return contentItem
|
||||||
.map(ContentItemModelData::getTitle)
|
.map(ContentItemModelData::getTitle)
|
||||||
.orElse("");
|
.orElse("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the description of the current item (see
|
||||||
|
* {@link ContentItem#description} for the current language (see
|
||||||
|
* {@link GlobalizationHelper#getNegotiatedLocale()}).
|
||||||
|
*
|
||||||
|
* @return The description of the current item for the current language, or
|
||||||
|
* an empty string if there is no item.
|
||||||
|
*/
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return getOrRetrieveContentItem()
|
init();
|
||||||
|
return contentItem
|
||||||
.map(ContentItemModelData::getDescription)
|
.map(ContentItemModelData::getDescription)
|
||||||
.orElse("");
|
.orElse("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the version of the current item (see {@link ContentItem#version}.
|
||||||
|
*
|
||||||
|
* @return The version of the current version as a string, or an empty
|
||||||
|
* string if there is not current item.
|
||||||
|
*/
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getVersion() {
|
public String getVersion() {
|
||||||
return getOrRetrieveContentItem()
|
init();
|
||||||
|
return contentItem
|
||||||
.map(ContentItemModelData::getVersion)
|
.map(ContentItemModelData::getVersion)
|
||||||
.orElse("");
|
.orElse("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the creation date/time of the current item (see
|
||||||
|
* {@link ContentItem#creationDate}.
|
||||||
|
*
|
||||||
|
* @return The creation date/time of the current item as ISO 8601 date/time
|
||||||
|
* string, or an empty string if there is no item.
|
||||||
|
*/
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getCreationDate() {
|
public String getCreationDate() {
|
||||||
return getOrRetrieveContentItem()
|
init();
|
||||||
|
return contentItem
|
||||||
.map(ContentItemModelData::getCreationDate)
|
.map(ContentItemModelData::getCreationDate)
|
||||||
.orElse("");
|
.orElse("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the date/time of the last modification of the current item (see
|
||||||
|
* {@link ContentItem#lastModified}.
|
||||||
|
*
|
||||||
|
* @return The date/time of the modification of the current item as ISO 8601
|
||||||
|
* date/time string, or an empty string of there is not current
|
||||||
|
* item.
|
||||||
|
*/
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getLastModified() {
|
public String getLastModified() {
|
||||||
return getOrRetrieveContentItem()
|
init();
|
||||||
|
return contentItem
|
||||||
.map(ContentItemModelData::getLastModified)
|
.map(ContentItemModelData::getLastModified)
|
||||||
.orElse("");
|
.orElse("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the user name of the user that created the item.
|
||||||
|
*
|
||||||
|
* @return The user name of the user that created the item.
|
||||||
|
*/
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getCreationUser() {
|
public String getCreationUser() {
|
||||||
return getOrRetrieveContentItem()
|
init();
|
||||||
|
return contentItem
|
||||||
.map(ContentItemModelData::getCreationUser)
|
.map(ContentItemModelData::getCreationUser)
|
||||||
.orElse("");
|
.orElse("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the user name of the user that did the last modifications on the
|
||||||
|
* item.
|
||||||
|
*
|
||||||
|
* @return The user name of the user that did the last modifications on the
|
||||||
|
* item.
|
||||||
|
*/
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getLastModifyingUserName() {
|
public String getLastModifyingUserName() {
|
||||||
return getOrRetrieveContentItem()
|
init();
|
||||||
|
return contentItem
|
||||||
.map(ContentItemModelData::getLastModifyingUserName)
|
.map(ContentItemModelData::getLastModifyingUserName)
|
||||||
.orElse("");
|
.orElse("");
|
||||||
}
|
}
|
||||||
|
|
||||||
// public List<AttachmentList> getAttachments() {
|
/**
|
||||||
// throw new UnsupportedOperationException("Not implemented yet.");
|
* Initialize the this model and all models implementing
|
||||||
// }
|
* {@link ProcessesContentItem#}.
|
||||||
// private Optional<ContentItem> getOrRetrieveContentItem() {
|
*
|
||||||
// if (contentItem == null) {
|
* If this model has not been initalizied already this method retrieves the
|
||||||
// retrieveContentItem();
|
* current content item using {@link #retrieveContentItem()}, and
|
||||||
// }
|
* initializes {@link #contentItem} with an instance of
|
||||||
// return contentItem;
|
* {@link ContentItemModelData} build from the item using
|
||||||
// }
|
* {@link #buildModelData(org.librecms.contentsection.ContentItem)}.
|
||||||
|
*
|
||||||
|
* After that, the method will invoke the implementation of
|
||||||
|
* {@link ProcessesContentItem#init(org.librecms.contentsection.ContentItem)}
|
||||||
|
* for all available implemetentations of {@link ProcessesContentItem} (see
|
||||||
|
* {@link #contentItemProcessingModels}).
|
||||||
|
*
|
||||||
|
* Models implementing SHOULD call this method in their getters before
|
||||||
|
* returning a value. There is not need to wrap the invocation of this
|
||||||
|
* method in an {@code if} statement, the method will only run its logic if
|
||||||
|
* the item has not been initialized.
|
||||||
|
*
|
||||||
|
* If there is no current item, the method will do nothing.
|
||||||
|
*/
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
private Optional<ContentItemModelData> getOrRetrieveContentItem() {
|
public void init() {
|
||||||
if (contentItem == null) {
|
if (contentItem != null) {
|
||||||
contentItem = retrieveContentItem().map(this::buildModelData);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Optional<ContentItem> item = retrieveContentItem();
|
||||||
|
contentItem = item.map(this::buildModelData);
|
||||||
|
|
||||||
|
final Iterator<ProcessesContentItem> iterator
|
||||||
|
= contentItemProcessingModels.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
final ProcessesContentItem model = iterator.next();
|
||||||
|
model.init(item.orElse(null));
|
||||||
}
|
}
|
||||||
return contentItem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method for retrieving the current content item. If
|
||||||
|
* {@link #itemName} is {@code null} or {@code index} the method will return
|
||||||
|
* if the index item of the current category. If the category has not index
|
||||||
|
* item, an empty {@link Optional} is returned.
|
||||||
|
*
|
||||||
|
* If {@link #itemName} is <b>not</b> {@code null} or {@code index}, the
|
||||||
|
* method will try to find a content item associated to the category where
|
||||||
|
* {@link ContentItem#name} matches {@link #itemName}.
|
||||||
|
*
|
||||||
|
* @return The current content item if any, or an empyty {@link Optional}.
|
||||||
|
*
|
||||||
|
* @see PagesService#findIndexItem(org.libreccm.categorization.Category,
|
||||||
|
* org.librecms.contentsection.ContentItemVersion)
|
||||||
|
* @see
|
||||||
|
* PagesService#findCategorizedItem(org.libreccm.categorization.Category,
|
||||||
|
* java.lang.String, org.librecms.contentsection.ContentItemVersion)
|
||||||
|
*/
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
protected Optional<ContentItem> retrieveContentItem() {
|
private Optional<ContentItem> retrieveContentItem() {
|
||||||
final Optional<ContentItem> item;
|
final Optional<ContentItem> item;
|
||||||
if (itemName == null || "index".equals(itemName)) {
|
if (itemName == null || "index".equals(itemName)) {
|
||||||
item = pagesService.findIndexItem(
|
item = pagesService.findIndexItem(
|
||||||
|
|
@ -245,6 +431,15 @@ public class ContentItemModel {
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method for building an instance {@link ContentItemModelData} for a
|
||||||
|
* {@link ContentItem}.
|
||||||
|
*
|
||||||
|
* @param item The source content item.
|
||||||
|
*
|
||||||
|
* @return An instance of {@link ContentItemModelData} for the provided
|
||||||
|
* content item.
|
||||||
|
*/
|
||||||
private ContentItemModelData buildModelData(final ContentItem item) {
|
private ContentItemModelData buildModelData(final ContentItem item) {
|
||||||
final ContentItemModelData data = new ContentItemModelData();
|
final ContentItemModelData data = new ContentItemModelData();
|
||||||
data.setObjectId(item.getObjectId());
|
data.setObjectId(item.getObjectId());
|
||||||
|
|
@ -292,6 +487,12 @@ public class ContentItemModel {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encapsulates the data of content item provided by this model. To avoid to
|
||||||
|
* have to many fields in this model class we use an internal class to
|
||||||
|
* encapsulate the data. The getters of the model class return the values
|
||||||
|
* from an instance of this class.
|
||||||
|
*/
|
||||||
private class ContentItemModelData {
|
private class ContentItemModelData {
|
||||||
|
|
||||||
private long objectId;
|
private long objectId;
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ import javax.transaction.Transactional;
|
||||||
*/
|
*/
|
||||||
@RequestScoped
|
@RequestScoped
|
||||||
@Named("CmsPagesContentItemTypeModel")
|
@Named("CmsPagesContentItemTypeModel")
|
||||||
public class ContentItemTypeModel {
|
public class ContentItemTypeModel implements ProcessesContentItem {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ContentItemModel contentItemModel;
|
private ContentItemModel contentItemModel;
|
||||||
|
|
@ -54,48 +54,55 @@ public class ContentItemTypeModel {
|
||||||
private Optional<ContentItemTypeModelData> contentType;
|
private Optional<ContentItemTypeModelData> contentType;
|
||||||
|
|
||||||
public long getContentTypeId() {
|
public long getContentTypeId() {
|
||||||
return getOrRetrieveContentType()
|
contentItemModel.init();
|
||||||
|
|
||||||
|
return contentType
|
||||||
.map(ContentItemTypeModelData::getTypeId)
|
.map(ContentItemTypeModelData::getTypeId)
|
||||||
.orElse(0L);
|
.orElse(0L);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUuid() {
|
public String getUuid() {
|
||||||
return getOrRetrieveContentType()
|
contentItemModel.init();
|
||||||
|
|
||||||
|
return contentType
|
||||||
.map(ContentItemTypeModelData::getUuid)
|
.map(ContentItemTypeModelData::getUuid)
|
||||||
.orElse("");
|
.orElse("");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDisplayName() {
|
public String getDisplayName() {
|
||||||
return getOrRetrieveContentType()
|
contentItemModel.init();
|
||||||
|
|
||||||
|
return contentType
|
||||||
.map(ContentItemTypeModelData::getDisplayName)
|
.map(ContentItemTypeModelData::getDisplayName)
|
||||||
.orElse("");
|
.orElse("");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getLabel() {
|
public String getLabel() {
|
||||||
return getOrRetrieveContentType()
|
contentItemModel.init();
|
||||||
|
|
||||||
|
return contentType
|
||||||
.map(ContentItemTypeModelData::getLabel)
|
.map(ContentItemTypeModelData::getLabel)
|
||||||
.orElse("");
|
.orElse("");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return getOrRetrieveContentType()
|
contentItemModel.init();
|
||||||
|
|
||||||
|
return contentType
|
||||||
.map(ContentItemTypeModelData::getDescription)
|
.map(ContentItemTypeModelData::getDescription)
|
||||||
.orElse("");
|
.orElse("");
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<ContentItemTypeModelData> getOrRetrieveContentType() {
|
|
||||||
if (contentType == null) {
|
|
||||||
retrieveContentType();
|
|
||||||
}
|
|
||||||
return contentType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
private void retrieveContentType() {
|
public void init(final ContentItem contentItem) {
|
||||||
contentType = contentItemModel.retrieveContentItem()
|
if (contentType != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
contentType = Optional
|
||||||
|
.ofNullable(contentItem)
|
||||||
.map(ContentItem::getContentType)
|
.map(ContentItem::getContentType)
|
||||||
.map(this::buildModelData);
|
.map(this::buildModelData);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,6 @@ import javax.enterprise.context.RequestScoped;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.transaction.Transactional;
|
import javax.transaction.Transactional;
|
||||||
import javax.ws.rs.WebApplicationException;
|
|
||||||
import javax.ws.rs.core.Response;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -40,7 +38,7 @@ import javax.ws.rs.core.Response;
|
||||||
*/
|
*/
|
||||||
@RequestScoped
|
@RequestScoped
|
||||||
@Named("CmsPagesEventModel")
|
@Named("CmsPagesEventModel")
|
||||||
public class EventModel {
|
public class EventModel implements ProcessesContentItem {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ContentItemModel contentItemModel;
|
private ContentItemModel contentItemModel;
|
||||||
|
|
@ -48,6 +46,8 @@ public class EventModel {
|
||||||
@Inject
|
@Inject
|
||||||
private GlobalizationHelper globalizationHelper;
|
private GlobalizationHelper globalizationHelper;
|
||||||
|
|
||||||
|
private boolean initialized;
|
||||||
|
|
||||||
private final DateTimeFormatter isoDateTimeFormatter;
|
private final DateTimeFormatter isoDateTimeFormatter;
|
||||||
|
|
||||||
private String title;
|
private String title;
|
||||||
|
|
@ -65,77 +65,67 @@ public class EventModel {
|
||||||
private String eventType;
|
private String eventType;
|
||||||
|
|
||||||
public EventModel() {
|
public EventModel() {
|
||||||
|
initialized = false;
|
||||||
isoDateTimeFormatter = DateTimeFormatter.ISO_DATE_TIME
|
isoDateTimeFormatter = DateTimeFormatter.ISO_DATE_TIME
|
||||||
.withZone(ZoneId.systemDefault());
|
.withZone(ZoneId.systemDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
if (title == null) {
|
contentItemModel.init();
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getText() {
|
public String getText() {
|
||||||
if (text == null) {
|
contentItemModel.init();
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getStartDateTime() {
|
public String getStartDateTime() {
|
||||||
if (startDateTime == null) {
|
contentItemModel.init();
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return startDateTime;
|
return startDateTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getEndDateTime() {
|
public String getEndDateTime() {
|
||||||
if (endDateTime == null) {
|
contentItemModel.init();
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return endDateTime;
|
return endDateTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getEventDate() {
|
public String getEventDate() {
|
||||||
if (eventDate == null) {
|
contentItemModel.init();
|
||||||
init();
|
|
||||||
}
|
|
||||||
return eventDate;
|
return eventDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getLocation() {
|
public String getLocation() {
|
||||||
if (location == null) {
|
contentItemModel.init();
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getEventType() {
|
public String getEventType() {
|
||||||
if (eventType == null) {
|
contentItemModel.init();
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return eventDate;
|
return eventType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
protected void init() {
|
public void init(final ContentItem contentItem) {
|
||||||
final ContentItem contentItem = contentItemModel
|
if (initialized) {
|
||||||
.retrieveContentItem()
|
return;
|
||||||
.orElse(null);
|
}
|
||||||
|
|
||||||
if (contentItem instanceof Event) {
|
if (contentItem instanceof Event) {
|
||||||
final Event event = (Event) contentItem;
|
final Event event = (Event) contentItem;
|
||||||
|
|
||||||
|
|
@ -169,15 +159,9 @@ public class EventModel {
|
||||||
.ofNullable(event.getEventType())
|
.ofNullable(event.getEventType())
|
||||||
.map(globalizationHelper::getValueFromLocalizedString)
|
.map(globalizationHelper::getValueFromLocalizedString)
|
||||||
.orElse("");
|
.orElse("");
|
||||||
} else {
|
|
||||||
throw new WebApplicationException(
|
|
||||||
"Current content item is not an event",
|
|
||||||
Response
|
|
||||||
.status(Response.Status.INTERNAL_SERVER_ERROR)
|
|
||||||
.entity("Current content item is not an event.")
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ import javax.ws.rs.core.Response;
|
||||||
*/
|
*/
|
||||||
@RequestScoped
|
@RequestScoped
|
||||||
@Named("CmsPagesMultiPartArticleModel")
|
@Named("CmsPagesMultiPartArticleModel")
|
||||||
public class MultiPartArticleModel {
|
public class MultiPartArticleModel implements ProcessesContentItem {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ContentItemModel contentItemModel;
|
private ContentItemModel contentItemModel;
|
||||||
|
|
@ -49,6 +49,8 @@ public class MultiPartArticleModel {
|
||||||
@Inject
|
@Inject
|
||||||
private GlobalizationHelper globalizationHelper;
|
private GlobalizationHelper globalizationHelper;
|
||||||
|
|
||||||
|
private boolean initialized;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private PageUrlModel pageUrlModel;
|
private PageUrlModel pageUrlModel;
|
||||||
|
|
||||||
|
|
@ -61,69 +63,62 @@ public class MultiPartArticleModel {
|
||||||
private String currentSectionTitle;
|
private String currentSectionTitle;
|
||||||
|
|
||||||
private String currentSectionText;
|
private String currentSectionText;
|
||||||
|
|
||||||
private List<MultiPartArticleSectionModel> sections;
|
private List<MultiPartArticleSectionModel> sections;
|
||||||
|
|
||||||
|
public MultiPartArticleModel() {
|
||||||
|
initialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
if (title == null) {
|
contentItemModel.init();
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getSummary() {
|
public String getSummary() {
|
||||||
if (summary == null) {
|
contentItemModel.init();
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return summary;
|
return summary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public List<String> getSectionTitles() {
|
public List<String> getSectionTitles() {
|
||||||
if (sectionTitles == null) {
|
contentItemModel.init();
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Collections.unmodifiableList(sectionTitles);
|
return Collections.unmodifiableList(sectionTitles);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getCurrentSectionTitle() {
|
public String getCurrentSectionTitle() {
|
||||||
if (currentSectionTitle == null) {
|
contentItemModel.init();
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return currentSectionTitle;
|
return currentSectionTitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getCurrentSectionText() {
|
public String getCurrentSectionText() {
|
||||||
if (currentSectionText == null) {
|
contentItemModel.init();
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return currentSectionText;
|
return currentSectionText;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public List<MultiPartArticleSectionModel> getSections() {
|
public List<MultiPartArticleSectionModel> getSections() {
|
||||||
if (sections == null) {
|
contentItemModel.init();
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Collections.unmodifiableList(sections);
|
return Collections.unmodifiableList(sections);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
protected void init() {
|
public void init(final ContentItem contentItem) {
|
||||||
final ContentItem contentItem = contentItemModel
|
if (initialized) {
|
||||||
.retrieveContentItem()
|
return;
|
||||||
.orElse(null);
|
}
|
||||||
|
|
||||||
if (contentItem instanceof MultiPartArticle) {
|
if (contentItem instanceof MultiPartArticle) {
|
||||||
final MultiPartArticle mpa = (MultiPartArticle) contentItem;
|
final MultiPartArticle mpa = (MultiPartArticle) contentItem;
|
||||||
|
|
||||||
|
|
@ -165,26 +160,20 @@ public class MultiPartArticleModel {
|
||||||
.ofNullable(mpa.getSections().get(currentSection).getTitle())
|
.ofNullable(mpa.getSections().get(currentSection).getTitle())
|
||||||
.map(globalizationHelper::getValueFromLocalizedString)
|
.map(globalizationHelper::getValueFromLocalizedString)
|
||||||
.orElse("");
|
.orElse("");
|
||||||
|
|
||||||
currentSectionText = Optional
|
currentSectionText = Optional
|
||||||
.ofNullable(mpa.getSections().get(currentSection).getText())
|
.ofNullable(mpa.getSections().get(currentSection).getText())
|
||||||
.map(globalizationHelper::getValueFromLocalizedString)
|
.map(globalizationHelper::getValueFromLocalizedString)
|
||||||
.orElse("");
|
.orElse("");
|
||||||
|
|
||||||
sections = mpa
|
sections = mpa
|
||||||
.getSections()
|
.getSections()
|
||||||
.stream()
|
.stream()
|
||||||
.map(this::buildSectionModel)
|
.map(this::buildSectionModel)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
} else {
|
|
||||||
throw new WebApplicationException(
|
|
||||||
"Current content item is not an MultiPartArticle",
|
|
||||||
Response
|
|
||||||
.status(Response.Status.INTERNAL_SERVER_ERROR)
|
|
||||||
.entity("Current content item is not an MultiPartArticle.")
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int readCurrentSection() {
|
private int readCurrentSection() {
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ import org.libreccm.l10n.GlobalizationHelper;
|
||||||
import org.librecms.contentsection.ContentItem;
|
import org.librecms.contentsection.ContentItem;
|
||||||
import org.librecms.contenttypes.News;
|
import org.librecms.contenttypes.News;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
@ -32,8 +31,6 @@ import javax.enterprise.context.RequestScoped;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.transaction.Transactional;
|
import javax.transaction.Transactional;
|
||||||
import javax.ws.rs.WebApplicationException;
|
|
||||||
import javax.ws.rs.core.Response;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -41,79 +38,79 @@ import javax.ws.rs.core.Response;
|
||||||
*/
|
*/
|
||||||
@RequestScoped
|
@RequestScoped
|
||||||
@Named("CmsPagesNewsModel")
|
@Named("CmsPagesNewsModel")
|
||||||
public class NewsModel {
|
public class NewsModel implements ProcessesContentItem {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ContentItemModel contentItemModel;
|
private ContentItemModel contentItemModel;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private GlobalizationHelper globalizationHelper;
|
private GlobalizationHelper globalizationHelper;
|
||||||
|
|
||||||
|
private boolean initialized;
|
||||||
|
|
||||||
private final DateTimeFormatter isoDateTimeFormatter;
|
private final DateTimeFormatter isoDateTimeFormatter;
|
||||||
|
|
||||||
private String title;
|
private String title;
|
||||||
|
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
private String text;
|
private String text;
|
||||||
|
|
||||||
private String releaseDateTime;
|
private String releaseDateTime;
|
||||||
|
|
||||||
private boolean homepage;
|
private boolean homepage;
|
||||||
|
|
||||||
public NewsModel() {
|
public NewsModel() {
|
||||||
|
initialized = false;
|
||||||
isoDateTimeFormatter = DateTimeFormatter.ISO_DATE_TIME
|
isoDateTimeFormatter = DateTimeFormatter.ISO_DATE_TIME
|
||||||
.withZone(ZoneId.systemDefault());
|
.withZone(ZoneId.systemDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
if (title == null) {
|
contentItemModel.init();
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
if (description == null) {
|
contentItemModel.init();
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getText() {
|
public String getText() {
|
||||||
if (text == null) {
|
contentItemModel.init();
|
||||||
init();
|
|
||||||
}
|
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getReleaseDateTime() {
|
public String getReleaseDateTime() {
|
||||||
if (releaseDateTime == null) {
|
contentItemModel.init();
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return releaseDateTime;
|
return releaseDateTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
|
||||||
public boolean getHomepage() {
|
|
||||||
return homepage;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
protected void init() {
|
public boolean getHomepage() {
|
||||||
final ContentItem contentItem = contentItemModel
|
contentItemModel.init();
|
||||||
.retrieveContentItem()
|
|
||||||
.orElse(null);
|
return homepage;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public void init(final ContentItem contentItem) {
|
||||||
|
if (initialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (contentItem instanceof News) {
|
if (contentItem instanceof News) {
|
||||||
final News news = (News) contentItem;
|
final News news = (News) contentItem;
|
||||||
|
|
||||||
title = Optional
|
title = Optional
|
||||||
.ofNullable(news.getTitle())
|
.ofNullable(news.getTitle())
|
||||||
.map(globalizationHelper::getValueFromLocalizedString)
|
.map(globalizationHelper::getValueFromLocalizedString)
|
||||||
|
|
@ -132,15 +129,9 @@ public class NewsModel {
|
||||||
.map(isoDateTimeFormatter::format)
|
.map(isoDateTimeFormatter::format)
|
||||||
.orElse("");
|
.orElse("");
|
||||||
homepage = news.isHomepage();
|
homepage = news.isHomepage();
|
||||||
} else {
|
|
||||||
throw new WebApplicationException(
|
|
||||||
"Current content item is not a news item.",
|
|
||||||
Response
|
|
||||||
.status(Response.Status.INTERNAL_SERVER_ERROR)
|
|
||||||
.entity("Current content item is not a new item.")
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2022 LibreCCM Foundation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.librecms.pages.models;
|
||||||
|
|
||||||
|
import org.hibernate.LazyInitializationException;
|
||||||
|
import org.librecms.contentsection.ContentItem;
|
||||||
|
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Models that provide data for the current content item (either the index item
|
||||||
|
* of a category or a selected content item) SHOULD implement this interface.
|
||||||
|
*
|
||||||
|
* This {@link ContentItemModel} collects all instances of classes implementing
|
||||||
|
* this interface and calls their implemententation of the
|
||||||
|
* {@link #init(org.librecms.contentsection.ContentItem)} method.
|
||||||
|
*
|
||||||
|
* For an example of an implementation please look at
|
||||||
|
* {@link ContentItemTypeModel}, {@link ArticleModel} or
|
||||||
|
* at {@link MultiPartArticleModel} for a more complex model.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public interface ProcessesContentItem {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initalizes a model providing the data of a content item for MVC
|
||||||
|
* templates.
|
||||||
|
*
|
||||||
|
* If the implementing model only provides data for specific sub classes of
|
||||||
|
* {@link ContentItem} the implementation MUST check the correct type using
|
||||||
|
* the {@code instanceof} operator. If the item is not a the correct type a
|
||||||
|
* implementation MUST gracefully ignore the item.
|
||||||
|
*
|
||||||
|
* To avoid a {@link LazyInitializationException} implementations SHOULD be
|
||||||
|
* annotated with {@link Transactional} and the
|
||||||
|
* {@link Transactional.TxType#REQUIRED}.
|
||||||
|
*
|
||||||
|
* @param item The item.
|
||||||
|
*/
|
||||||
|
void init(ContentItem item);
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue