/*
* Copyright (C) 2017 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.pagemodel;
import com.arsdigita.kernel.KernelConfig;
import org.libreccm.categorization.CategoryManager;
import org.libreccm.categorization.CategoryRepository;
import org.libreccm.configuration.ConfigurationManager;
import org.libreccm.core.UnexpectedErrorException;
import org.libreccm.l10n.LocalizedString;
import org.libreccm.pagemodel.ComponentBuilder;
import org.libreccm.pagemodel.ComponentModel;
import org.libreccm.security.PermissionChecker;
import org.librecms.contentsection.ContentItem;
import org.librecms.contentsection.ContentItemL10NManager;
import org.librecms.contentsection.ContentItemManager;
import org.librecms.contentsection.privileges.ItemPrivileges;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import javax.inject.Inject;
import javax.transaction.Transactional;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import static org.librecms.pages.PagesConstants.*;
/**
*
* @author Jens Pelzetter
* @param
*/
public abstract class AbstractContentItemComponentBuilder
implements ComponentBuilder {
@Inject
private ConfigurationManager confManager;
@Inject
private ContentItemL10NManager iteml10nManager;
@Inject
private ContentItemManager itemManager;
@Inject
private PermissionChecker permissionChecker;
protected abstract ContentItem getContentItem(
T componentModel, final Map parameters);
@Transactional(Transactional.TxType.REQUIRED)
@Override
public Map buildComponent(
final T componentModel,
final Map parameters) {
Objects.requireNonNull(componentModel);
Objects.requireNonNull(parameters);
final ContentItem contentItem = getContentItem(componentModel,
parameters);
if (Boolean.TRUE.equals(parameters.get("showDraftItem"))) {
final ContentItem draftItem = itemManager
.getDraftVersion(contentItem, contentItem.getClass());
if (permissionChecker.isPermitted(ItemPrivileges.PREVIEW, draftItem)) {
final Map result = generateItem(componentModel,
parameters,
draftItem);
result.put("showDraftItem", Boolean.TRUE);
return result;
} else {
throw new WebApplicationException(
"You are not permitted to view the draft version of this item.",
Response.Status.UNAUTHORIZED);
}
} else {
final ContentItem liveItem = itemManager
.getLiveVersion(contentItem, contentItem.getClass())
.orElseThrow(() -> new NotFoundException(
"This content item does not "
+ "have a live version."));
if (permissionChecker.isPermitted(ItemPrivileges.VIEW_PUBLISHED,
liveItem)) {
return generateItem(componentModel,
parameters,
liveItem);
} else {
throw new WebApplicationException(
"You are not permitted to view the live version of "
+ "this item.",
Response.Status.UNAUTHORIZED);
}
}
}
protected Map generateItem(
final T componentModel,
final Map parameters,
final ContentItem item) {
final Locale language;
if (parameters.containsKey("language")) {
language = new Locale((String) parameters.get(PARAMETER_LANGUAGE));
} else {
final KernelConfig kernelConfig = confManager
.findConfiguration(KernelConfig.class);
language = kernelConfig.getDefaultLocale();
}
if (iteml10nManager.hasLanguage(item, language)) {
final BeanInfo beanInfo;
try {
beanInfo = Introspector.getBeanInfo(item.getClass());
} catch (IntrospectionException ex) {
throw new UnexpectedErrorException(ex);
}
final PropertyDescriptor[] properties = beanInfo
.getPropertyDescriptors();
final Map result = new HashMap<>();
for (final PropertyDescriptor propertyDescriptor : properties) {
renderProperty(propertyDescriptor,
componentModel,
language,
item,
result);
}
return result;
} else {
throw new NotFoundException("Requested language is not available.");
}
}
protected void renderProperty(final PropertyDescriptor propertyDescriptor,
final T componentModel,
final Locale language,
final ContentItem item,
final Map result) {
final String propertyName = propertyDescriptor.getName();
if (componentModel.getExcludedPropertyPaths().contains(propertyName)) {
return;
}
final Method readMethod = propertyDescriptor.getReadMethod();
if (Collection.class.isAssignableFrom(propertyDescriptor
.getPropertyType())) {
final Collection> collection;
try {
collection = (Collection>) readMethod.invoke(item);
} catch (IllegalAccessException | InvocationTargetException ex) {
throw new UnexpectedErrorException(ex);
}
final List