Model for item lists
parent
8b3f18582f
commit
c689ed536c
|
|
@ -29,14 +29,15 @@ import javax.inject.Inject;
|
||||||
* @param <T>
|
* @param <T>
|
||||||
* @param <M>
|
* @param <M>
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractContentItemListModelBuilder<T extends ContentItem, M extends AbstractContentItemListItemModel>
|
public abstract class AbstractContentItemListItemModelBuilder<T extends ContentItem, M extends AbstractContentItemListItemModel>
|
||||||
implements ContentItemListItemModelBuilder<T, M> {
|
implements ContentItemListItemModelBuilder<T, M> {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private GlobalizationHelper globalizationHelper;
|
private GlobalizationHelper globalizationHelper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public M buildListItemModel(final T contentItem) {
|
@SuppressWarnings("unchecked")
|
||||||
|
public M buildListItemModel(final ContentItem contentItem) {
|
||||||
final M model = buildModel();
|
final M model = buildModel();
|
||||||
model.setDescription(
|
model.setDescription(
|
||||||
globalizationHelper.getValueFromLocalizedString(
|
globalizationHelper.getValueFromLocalizedString(
|
||||||
|
|
@ -53,7 +54,7 @@ public abstract class AbstractContentItemListModelBuilder<T extends ContentItem,
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
addProperties(contentItem, model);
|
addProperties((T) contentItem, model);
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
@ -28,7 +28,7 @@ import javax.enterprise.context.RequestScoped;
|
||||||
*/
|
*/
|
||||||
@RequestScoped
|
@RequestScoped
|
||||||
public class ArticleListItemModelBuilder
|
public class ArticleListItemModelBuilder
|
||||||
extends AbstractContentItemListModelBuilder<Article, ArticleListItemModel> {
|
extends AbstractContentItemListItemModelBuilder<Article, ArticleListItemModel> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ArticleListItemModel buildModel() {
|
protected ArticleListItemModel buildModel() {
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ import org.librecms.contentsection.ContentItem;
|
||||||
*/
|
*/
|
||||||
public interface ContentItemListItemModelBuilder<T extends ContentItem, M extends AbstractContentItemListItemModel> {
|
public interface ContentItemListItemModelBuilder<T extends ContentItem, M extends AbstractContentItemListItemModel> {
|
||||||
|
|
||||||
M buildListItemModel(T contentItem);
|
M buildListItemModel(ContentItem contentItem);
|
||||||
|
|
||||||
Class<T> buildsListItemModelFor();
|
Class<T> buildsListItemModelFor();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ import javax.inject.Inject;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
public class EventListItemModelBuilder
|
public class EventListItemModelBuilder
|
||||||
extends AbstractContentItemListModelBuilder<Event, EventListItemModel> {
|
extends AbstractContentItemListItemModelBuilder<Event, EventListItemModel> {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private GlobalizationHelper globalizationHelper;
|
private GlobalizationHelper globalizationHelper;
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ package org.librecms.pages.models;
|
||||||
|
|
||||||
import org.libreccm.l10n.GlobalizationHelper;
|
import org.libreccm.l10n.GlobalizationHelper;
|
||||||
import org.librecms.contentsection.ContentItem;
|
import org.librecms.contentsection.ContentItem;
|
||||||
import org.librecms.contenttypes.Article;
|
|
||||||
import org.librecms.contenttypes.Event;
|
import org.librecms.contenttypes.Event;
|
||||||
|
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
|
|
@ -47,13 +46,15 @@ public class EventModel {
|
||||||
private GlobalizationHelper globalizationHelper;
|
private GlobalizationHelper globalizationHelper;
|
||||||
|
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
return globalizationHelper
|
return globalizationHelper.getValueFromLocalizedString(
|
||||||
.getValueFromLocalizedString(getEvent().getTitle());
|
getEvent().getTitle()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getText() {
|
public String getText() {
|
||||||
return globalizationHelper
|
return globalizationHelper.getValueFromLocalizedString(
|
||||||
.getValueFromLocalizedString(getEvent().getText());
|
getEvent().getText()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getStartDateTime() {
|
public String getStartDateTime() {
|
||||||
|
|
@ -69,13 +70,15 @@ public class EventModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getEventDate() {
|
public String getEventDate() {
|
||||||
return globalizationHelper
|
return globalizationHelper.getValueFromLocalizedString(
|
||||||
.getValueFromLocalizedString(getEvent().getEventDate());
|
getEvent().getEventDate()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getLocation() {
|
public String getLocation() {
|
||||||
return globalizationHelper.
|
return globalizationHelper.getValueFromLocalizedString(
|
||||||
getValueFromLocalizedString(getEvent().getLocation());
|
getEvent().getLocation()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Event getEvent() {
|
protected Event getEvent() {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,412 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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 com.arsdigita.kernel.KernelConfig;
|
||||||
|
|
||||||
|
import org.libreccm.categorization.Categorization;
|
||||||
|
import org.libreccm.categorization.Category;
|
||||||
|
import org.libreccm.configuration.ConfigurationManager;
|
||||||
|
import org.libreccm.core.UnexpectedErrorException;
|
||||||
|
import org.libreccm.l10n.GlobalizationHelper;
|
||||||
|
import org.libreccm.security.Permission;
|
||||||
|
import org.libreccm.security.PermissionChecker;
|
||||||
|
import org.libreccm.security.Role;
|
||||||
|
import org.libreccm.security.RoleManager;
|
||||||
|
import org.libreccm.security.Shiro;
|
||||||
|
import org.libreccm.security.User;
|
||||||
|
import org.libreccm.security.UserRepository;
|
||||||
|
import org.librecms.contentsection.ContentItem;
|
||||||
|
import org.librecms.contentsection.ContentItemL10NManager;
|
||||||
|
import org.librecms.contentsection.ContentItemVersion;
|
||||||
|
import org.librecms.contentsection.privileges.ItemPrivileges;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.criteria.CriteriaBuilder;
|
||||||
|
import javax.persistence.criteria.CriteriaQuery;
|
||||||
|
import javax.persistence.criteria.Join;
|
||||||
|
import javax.persistence.criteria.JoinType;
|
||||||
|
import javax.persistence.criteria.Order;
|
||||||
|
import javax.persistence.criteria.Predicate;
|
||||||
|
import javax.persistence.criteria.Root;
|
||||||
|
import javax.ws.rs.WebApplicationException;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@RequestScoped
|
||||||
|
@Named("CmsPagesItemListModel")
|
||||||
|
public class ItemListModel {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private CategoryModel categoryModel;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ConfigurationManager confManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ContentItemL10NManager itemL10NManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ContentItemListItemModelBuilders listItemModelBuilders;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private GlobalizationHelper globalizationHelper;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private EntityManager entityManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private PermissionChecker permissionChecker;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private RoleManager roleManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private UserRepository userRepo;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Shiro shiro;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private PageUrlModel pageUrlModel;
|
||||||
|
|
||||||
|
private boolean descending;
|
||||||
|
|
||||||
|
private String limitToType;
|
||||||
|
|
||||||
|
private List<String> listOrder;
|
||||||
|
|
||||||
|
private int pageSize;
|
||||||
|
|
||||||
|
private List<? extends AbstractContentItemListItemModel> itemList;
|
||||||
|
|
||||||
|
public ItemListModel() {
|
||||||
|
descending = false;
|
||||||
|
limitToType = ContentItem.class.getName();
|
||||||
|
listOrder = List.of(ContentItem.class.getName());
|
||||||
|
pageSize = 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDescending() {
|
||||||
|
return descending;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescending(final boolean descending) {
|
||||||
|
this.descending = descending;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLimitToType() {
|
||||||
|
return limitToType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLimitToType(final String limitToType) {
|
||||||
|
this.limitToType = limitToType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getListOrder() {
|
||||||
|
return Collections.unmodifiableList(listOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setListOrder(final List<String> listOrder) {
|
||||||
|
this.listOrder = new ArrayList<>(listOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPageSize() {
|
||||||
|
return pageSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPageSize(final int pageSize) {
|
||||||
|
this.pageSize = pageSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFirstItem() {
|
||||||
|
return getOffset(pageSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getListSize() {
|
||||||
|
return getItems().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<? extends AbstractContentItemListItemModel> getItems() {
|
||||||
|
if (itemList == null) {
|
||||||
|
buildList(
|
||||||
|
buildLimitToType(limitToType),
|
||||||
|
collectCategories(categoryModel.getCategory()),
|
||||||
|
listOrder,
|
||||||
|
pageSize
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Collections.unmodifiableList(itemList);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildList(
|
||||||
|
final Class<? extends ContentItem> limitToType,
|
||||||
|
final List<Category> categories,
|
||||||
|
final List<String> listOrder,
|
||||||
|
final int pageSize
|
||||||
|
) {
|
||||||
|
final CriteriaBuilder criteriaBuilder = entityManager
|
||||||
|
.getCriteriaBuilder();
|
||||||
|
final CriteriaQuery<? extends ContentItem> criteriaQuery
|
||||||
|
= criteriaBuilder
|
||||||
|
.createQuery(limitToType);
|
||||||
|
final Root<? extends ContentItem> from = criteriaQuery
|
||||||
|
.from(limitToType);
|
||||||
|
final Join<? extends ContentItem, Categorization> catJoin = from
|
||||||
|
.join("categories");
|
||||||
|
final Join<? extends ContentItem, Permission> permissionsJoin = from
|
||||||
|
.join("permissions", JoinType.LEFT);
|
||||||
|
|
||||||
|
criteriaQuery
|
||||||
|
.distinct(true)
|
||||||
|
.where(
|
||||||
|
criteriaBuilder.and(
|
||||||
|
catJoin.get("category").in(categories),
|
||||||
|
criteriaBuilder.equal(catJoin.get("indexObject"), false),
|
||||||
|
criteriaBuilder.equal(catJoin.get("type"), ""),
|
||||||
|
criteriaBuilder.equal(
|
||||||
|
from.get("version"), ContentItemVersion.LIVE
|
||||||
|
),
|
||||||
|
buildPermissionsCheck(
|
||||||
|
criteriaBuilder, from, permissionsJoin
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
criteriaQuery.orderBy(
|
||||||
|
listOrder
|
||||||
|
.stream()
|
||||||
|
.map(order -> builderOrder(order, from, criteriaBuilder))
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
);
|
||||||
|
|
||||||
|
itemList = entityManager
|
||||||
|
.createQuery(criteriaQuery)
|
||||||
|
.getResultList()
|
||||||
|
.stream()
|
||||||
|
.filter(
|
||||||
|
item -> itemL10NManager.hasLanguage(
|
||||||
|
item, globalizationHelper.getNegotiatedLocale()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.skip(getOffset(pageSize))
|
||||||
|
.limit(pageSize)
|
||||||
|
.map(this::buildListItemModel)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Category> collectCategories(final Category category) {
|
||||||
|
|
||||||
|
if (category.getSubCategories().isEmpty()) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
} else {
|
||||||
|
final List<Category> categories = new ArrayList<>();
|
||||||
|
for (final Category subCategory : category.getSubCategories()) {
|
||||||
|
categories.add(subCategory);
|
||||||
|
categories.addAll(collectCategories(subCategory));
|
||||||
|
}
|
||||||
|
return categories;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Class<? extends ContentItem> buildLimitToType(
|
||||||
|
final String className
|
||||||
|
) {
|
||||||
|
if (className == null || className.isBlank()) {
|
||||||
|
return ContentItem.class;
|
||||||
|
} else {
|
||||||
|
final Class<?> clazz;
|
||||||
|
try {
|
||||||
|
clazz = Class.forName(className);
|
||||||
|
} catch (ClassNotFoundException ex) {
|
||||||
|
throw new UnexpectedErrorException(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ContentItem.class.isAssignableFrom(clazz)) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final Class<? extends ContentItem> type
|
||||||
|
= (Class<? extends ContentItem>) clazz;
|
||||||
|
return type;
|
||||||
|
} else {
|
||||||
|
throw new UnexpectedErrorException(String
|
||||||
|
.format(
|
||||||
|
"The type \"%s\" set in ItemList is not a subtype of "
|
||||||
|
+ "\"%s\".",
|
||||||
|
clazz.getName(),
|
||||||
|
ContentItem.class.getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Predicate buildPermissionsCheck(
|
||||||
|
final CriteriaBuilder criteriaBuilder,
|
||||||
|
final Root<? extends ContentItem> from,
|
||||||
|
final Join<? extends ContentItem, Permission> permissionsJoin
|
||||||
|
) {
|
||||||
|
final List<Role> roles = retrieveCurrentRoles();
|
||||||
|
|
||||||
|
final boolean isSystemUser = shiro.isSystemUser();
|
||||||
|
final boolean isAdmin = permissionChecker.isPermitted("*");
|
||||||
|
|
||||||
|
final Predicate permissionsCheck;
|
||||||
|
if (roles.isEmpty()) {
|
||||||
|
permissionsCheck = criteriaBuilder
|
||||||
|
.or(
|
||||||
|
criteriaBuilder.equal(criteriaBuilder.literal(true),
|
||||||
|
isSystemUser),
|
||||||
|
criteriaBuilder.equal(criteriaBuilder.literal(true),
|
||||||
|
isAdmin)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
permissionsCheck = criteriaBuilder
|
||||||
|
.or(
|
||||||
|
criteriaBuilder
|
||||||
|
.and(
|
||||||
|
criteriaBuilder.in(permissionsJoin.get("grantee"))
|
||||||
|
.value(roles),
|
||||||
|
criteriaBuilder
|
||||||
|
.equal(
|
||||||
|
permissionsJoin.get("grantedPrivilege"),
|
||||||
|
criteriaBuilder.selectCase()
|
||||||
|
.when(
|
||||||
|
criteriaBuilder.equal(
|
||||||
|
from.get("version"),
|
||||||
|
ContentItemVersion.DRAFT),
|
||||||
|
ItemPrivileges.PREVIEW)
|
||||||
|
.otherwise(
|
||||||
|
ItemPrivileges.VIEW_PUBLISHED))
|
||||||
|
),
|
||||||
|
criteriaBuilder
|
||||||
|
.equal(criteriaBuilder.literal(true),
|
||||||
|
isSystemUser),
|
||||||
|
criteriaBuilder
|
||||||
|
.equal(criteriaBuilder.literal(true),
|
||||||
|
isAdmin)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return permissionsCheck;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Role> retrieveCurrentRoles() {
|
||||||
|
final Optional<User> user = shiro.getUser();
|
||||||
|
final List<Role> roles;
|
||||||
|
if (user.isPresent()) {
|
||||||
|
final User theUser = userRepo
|
||||||
|
.findById(user.get().getPartyId())
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException(String
|
||||||
|
.format(
|
||||||
|
"No user with id %d in the database. "
|
||||||
|
+ "Where did that ID come from?",
|
||||||
|
user.get().getPartyId())));
|
||||||
|
roles = roleManager.findAllRolesForUser(theUser);
|
||||||
|
} else {
|
||||||
|
final Optional<User> publicUser;
|
||||||
|
|
||||||
|
final KernelConfig kernelConfig = confManager
|
||||||
|
.findConfiguration(KernelConfig.class);
|
||||||
|
final String principal = (String) shiro
|
||||||
|
.getPublicUser()
|
||||||
|
.getPrincipal();
|
||||||
|
if (kernelConfig.emailIsPrimaryIdentifier()) {
|
||||||
|
publicUser = userRepo.findByEmailAddress(principal);
|
||||||
|
} else {
|
||||||
|
publicUser = userRepo.findByName(principal);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (publicUser.isPresent()) {
|
||||||
|
roles = roleManager.findAllRolesForUser(publicUser.get());
|
||||||
|
} else {
|
||||||
|
roles = Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Order builderOrder(
|
||||||
|
final String order,
|
||||||
|
final Root<? extends ContentItem> from,
|
||||||
|
final CriteriaBuilder criteriaBuilder
|
||||||
|
) {
|
||||||
|
if (order.endsWith(" ASC")) {
|
||||||
|
final String colName = order
|
||||||
|
.substring(0, order.length() - " ASC".length());
|
||||||
|
return (criteriaBuilder.asc(from.get(colName)));
|
||||||
|
} else if (order.endsWith(" DESC")) {
|
||||||
|
final String colName = order
|
||||||
|
.substring(0, order.length() - " DESC".length());
|
||||||
|
return criteriaBuilder.desc(from.get(colName));
|
||||||
|
} else {
|
||||||
|
return criteriaBuilder.asc(from.get(order));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getOffset(final int pageSize) {
|
||||||
|
if (pageUrlModel.getQueryParameters().containsKey("page")) {
|
||||||
|
final String value = pageUrlModel.getQueryParameters().get("page");
|
||||||
|
if (value.matches("\\d*")) {
|
||||||
|
final int page = Integer.valueOf(value);
|
||||||
|
|
||||||
|
return page * pageSize;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private AbstractContentItemListItemModel buildListItemModel(
|
||||||
|
final ContentItem contentItem
|
||||||
|
) {
|
||||||
|
final ContentItemListItemModelBuilder<?, ?> builder
|
||||||
|
= listItemModelBuilders.getModelBuilderFor(contentItem.getClass())
|
||||||
|
.orElseThrow(
|
||||||
|
() -> new WebApplicationException(
|
||||||
|
Response
|
||||||
|
.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||||
|
.entity(
|
||||||
|
String.format(
|
||||||
|
"No ListItemModelBuilder for content item "
|
||||||
|
+ "type %s available.",
|
||||||
|
contentItem.getClass().getName()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return builder.buildListItemModel(contentItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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.librecms.contenttypes.MultiPartArticle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class MultiPartArticleListItemModel
|
||||||
|
extends AbstractContentItemListItemModel {
|
||||||
|
|
||||||
|
private String summary;
|
||||||
|
|
||||||
|
public String getSummary() {
|
||||||
|
return summary;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setSummary(final String summary) {
|
||||||
|
this.summary = summary;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return MultiPartArticle.class.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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.libreccm.l10n.GlobalizationHelper;
|
||||||
|
import org.librecms.contenttypes.MultiPartArticle;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class MultiPartArticleListItemModelBuilder
|
||||||
|
extends AbstractContentItemListItemModelBuilder<MultiPartArticle, MultiPartArticleListItemModel> {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private GlobalizationHelper globalizationHelper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<MultiPartArticle> buildsListItemModelFor() {
|
||||||
|
return MultiPartArticle.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected MultiPartArticleListItemModel buildModel() {
|
||||||
|
return new MultiPartArticleListItemModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addProperties(
|
||||||
|
final MultiPartArticle article,
|
||||||
|
final MultiPartArticleListItemModel model
|
||||||
|
) {
|
||||||
|
super.addProperties(article, model);
|
||||||
|
model.setSummary(
|
||||||
|
globalizationHelper.getValueFromLocalizedString(
|
||||||
|
article.getSummary()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,168 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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.libreccm.l10n.GlobalizationHelper;
|
||||||
|
import org.librecms.contentsection.ContentItem;
|
||||||
|
import org.librecms.contenttypes.MultiPartArticle;
|
||||||
|
import org.librecms.contenttypes.MultiPartArticleSection;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.ws.rs.WebApplicationException;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@RequestScoped
|
||||||
|
@Named("CmsPagesMultiPartArticleModel")
|
||||||
|
public class MultiPartArticleModel {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ContentItemModel contentItemModel;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private GlobalizationHelper globalizationHelper;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private PageUrlModel pageUrlModel;
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return globalizationHelper.getValueFromLocalizedString(
|
||||||
|
getMultiPartArticle().getTitle()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSummary() {
|
||||||
|
return globalizationHelper.getValueFromLocalizedString(
|
||||||
|
getMultiPartArticle().getSummary()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getSectionTitles() {
|
||||||
|
return getMultiPartArticle()
|
||||||
|
.getSections()
|
||||||
|
.stream()
|
||||||
|
.map(MultiPartArticleSection::getTitle)
|
||||||
|
.map(globalizationHelper::getValueFromLocalizedString)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCurrentSectionTitle() {
|
||||||
|
final int currentSection = readCurrentSection();
|
||||||
|
if (getMultiPartArticle().getSections().size() > currentSection) {
|
||||||
|
throw new WebApplicationException(
|
||||||
|
Response
|
||||||
|
.status(Response.Status.NOT_FOUND)
|
||||||
|
.entity(
|
||||||
|
String.format(
|
||||||
|
"MultiPartArticle %s has not section %d.",
|
||||||
|
getMultiPartArticle().getDisplayName(),
|
||||||
|
currentSection
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return globalizationHelper.getValueFromLocalizedString(
|
||||||
|
getMultiPartArticle().getSections().get(currentSection).getTitle()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCurrentSectionText() {
|
||||||
|
final int currentSection = readCurrentSection();
|
||||||
|
if (getMultiPartArticle().getSections().size() > currentSection) {
|
||||||
|
throw new WebApplicationException(
|
||||||
|
Response
|
||||||
|
.status(Response.Status.NOT_FOUND)
|
||||||
|
.entity(
|
||||||
|
String.format(
|
||||||
|
"MultiPartArticle %s has not section %d.",
|
||||||
|
getMultiPartArticle().getDisplayName(),
|
||||||
|
currentSection
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return globalizationHelper.getValueFromLocalizedString(
|
||||||
|
getMultiPartArticle().getSections().get(currentSection).getText()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<MultiPartArticleSectionModel> getSections() {
|
||||||
|
return getMultiPartArticle()
|
||||||
|
.getSections()
|
||||||
|
.stream()
|
||||||
|
.map(this::buildSectionModel)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected MultiPartArticle getMultiPartArticle() {
|
||||||
|
final ContentItem contentItem = contentItemModel.getContentItem();
|
||||||
|
if (contentItem instanceof MultiPartArticle) {
|
||||||
|
return (MultiPartArticle) contentItem;
|
||||||
|
} 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()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int readCurrentSection() {
|
||||||
|
if (pageUrlModel.getPath().matches(".*/@sections/[0-9]*$")) {
|
||||||
|
final String[] tokens = pageUrlModel.getPath().split("/");
|
||||||
|
return Integer.valueOf(tokens[tokens.length - 1]) - 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private MultiPartArticleSectionModel buildSectionModel(
|
||||||
|
final MultiPartArticleSection fromSection
|
||||||
|
) {
|
||||||
|
final MultiPartArticleSectionModel model
|
||||||
|
= new MultiPartArticleSectionModel();
|
||||||
|
model.setTitle(
|
||||||
|
globalizationHelper.getValueFromLocalizedString(
|
||||||
|
fromSection.getTitle()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
model.setText(
|
||||||
|
globalizationHelper.getValueFromLocalizedString(
|
||||||
|
fromSection.getText()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class MultiPartArticleSectionModel {
|
||||||
|
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setTitle(final String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setText(final String text) {
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -27,7 +27,7 @@ import java.time.LocalDateTime;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
public class NewsListItemModelBuilder
|
public class NewsListItemModelBuilder
|
||||||
extends AbstractContentItemListModelBuilder<News, NewsListItemModel> {
|
extends AbstractContentItemListItemModelBuilder<News, NewsListItemModel> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<News> buildsListItemModelFor() {
|
public Class<News> buildsListItemModelFor() {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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 java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model initalized by the Pages application containing information about the
|
||||||
|
* URL requested.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@RequestScoped
|
||||||
|
@Named("CmsPagesPageUrlModel")
|
||||||
|
public class PageUrlModel {
|
||||||
|
|
||||||
|
private String protocol;
|
||||||
|
|
||||||
|
private String host;
|
||||||
|
|
||||||
|
private int port;
|
||||||
|
|
||||||
|
private String path;
|
||||||
|
|
||||||
|
private Map<String, String> queryParameters;
|
||||||
|
|
||||||
|
public String getProtocol() {
|
||||||
|
return protocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProtocol(final String protocol) {
|
||||||
|
this.protocol = protocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHost() {
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHost(final String host) {
|
||||||
|
this.host = host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPort() {
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPort(final int port) {
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPath() {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPath(final String path) {
|
||||||
|
this.path = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PageUrlModel() {
|
||||||
|
queryParameters = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getQueryParameters() {
|
||||||
|
return Collections.unmodifiableMap(queryParameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addQueryParameter(final String key, final String value) {
|
||||||
|
queryParameters.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQueryParameters(final Map<String, String> queryParameters) {
|
||||||
|
this.queryParameters = new HashMap<>(queryParameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue