From 6300b386760da93d7c5e5845df3af6d555bfcf18 Mon Sep 17 00:00:00 2001 From: jensp Date: Tue, 28 Nov 2017 19:35:02 +0000 Subject: [PATCH] CCM NG: Several small bugfixes git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@5146 8810af33-2d31-482b-a856-94f89814c4df --- .../src/main/resources/log4j2.xml | 7 +- .../cms/ui/category/CategoryAdminPane.java | 91 ++++--- .../ui/pagemodel/ItemListComponentForm.java | 54 ++-- .../cms/ui/pages/PagesAdminPage.java | 4 +- ccm-cms/src/main/java/org/librecms/Cms.java | 1 + .../librecms/pagemodel/ItemListComponent.java | 6 +- .../org/librecms/CmsResources.properties | 1 + .../org/librecms/CmsResources_de.properties | 1 + .../org/librecms/CmsResources_fr.properties | 1 + .../ui/admin/pagemodels/PageModelDetails.java | 82 ++++-- .../pagemodels/PageModelsController.java | 4 +- .../admin/ui/ApplicationTreeDataProvider.java | 21 +- .../org/libreccm/admin/ui/PageModelsTab.java | 30 ++- .../admin/ui/PageModelsTableDataProvider.java | 19 +- .../org/libreccm/pagemodel/PageModel.java | 52 +++- .../libreccm/pagemodel/PageModelManager.java | 56 ++-- .../pagemodel/PageModelRepository.java | 239 +++++++++++++++--- .../libreccm/pagemodel/ui/PageTreeModel.java | 2 +- .../main/java/org/libreccm/sites/Site.java | 2 +- .../ui/admin/AdminResources.properties | 10 +- .../ui/admin/AdminResources_de.properties | 10 +- .../ui/admin/AdminResources_en.properties | 10 +- .../ui/admin/AdminResources_fr.properties | 10 +- 23 files changed, 547 insertions(+), 166 deletions(-) diff --git a/ccm-bundle-devel-wildfly-web/src/main/resources/log4j2.xml b/ccm-bundle-devel-wildfly-web/src/main/resources/log4j2.xml index 9c55f1436..4927cf628 100644 --- a/ccm-bundle-devel-wildfly-web/src/main/resources/log4j2.xml +++ b/ccm-bundle-devel-wildfly-web/src/main/resources/log4j2.xml @@ -68,6 +68,9 @@ + + @@ -92,8 +95,8 @@ - - \ No newline at end of file + diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryAdminPane.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryAdminPane.java index c6a275982..d73251a8b 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryAdminPane.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryAdminPane.java @@ -18,11 +18,22 @@ */ package com.arsdigita.cms.ui.category; -import com.arsdigita.bebop.*; -import com.arsdigita.bebop.event.*; +import com.arsdigita.bebop.ActionLink; +import com.arsdigita.bebop.Form; +import com.arsdigita.bebop.FormProcessException; +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.List; +import com.arsdigita.bebop.Page; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.ParameterSingleSelectionModel; +import com.arsdigita.bebop.SimpleContainer; +import com.arsdigita.bebop.SingleSelectionModel; +import com.arsdigita.bebop.Tree; +import com.arsdigita.bebop.event.ChangeEvent; +import com.arsdigita.bebop.event.ChangeListener; +import com.arsdigita.bebop.event.FormSectionEvent; import com.arsdigita.bebop.parameters.ParameterModel; import com.arsdigita.bebop.parameters.StringParameter; -import com.arsdigita.cms.CMS; import com.arsdigita.cms.ui.BaseAdminPane; import com.arsdigita.cms.ui.BaseDeleteForm; import com.arsdigita.cms.ui.BaseTree; @@ -30,17 +41,18 @@ import com.arsdigita.cms.ui.VisibilityComponent; import com.arsdigita.toolbox.ui.ActionGroup; import com.arsdigita.toolbox.ui.Section; import com.arsdigita.xml.Element; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.libreccm.categorization.Categorization; import org.libreccm.categorization.Category; -import org.libreccm.categorization.CategoryManager; import org.libreccm.categorization.CategoryRepository; import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.core.UnexpectedErrorException; import org.libreccm.security.PermissionChecker; import org.librecms.contentsection.privileges.AdminPrivileges; -import java.math.BigDecimal; + /** * A split pane for the Category Administration UI. @@ -53,7 +65,7 @@ public final class CategoryAdminPane extends BaseAdminPane { public static final String CONTEXT_SELECTED = "sel_context"; private static final String DEFAULT_USE_CONTEXT = ""; private static final Logger LOGGER = LogManager.getLogger( - CategoryAdminPane.class); + CategoryAdminPane.class); private final SingleSelectionModel m_contextModel; private final Tree m_categoryTree; private final SingleSelectionModel m_model; @@ -63,16 +75,18 @@ public final class CategoryAdminPane extends BaseAdminPane { public CategoryAdminPane() { super(); - m_contextModel = new UseContextSelectionModel(new StringParameter(CONTEXT_SELECTED)); + m_contextModel = new UseContextSelectionModel(new StringParameter( + CONTEXT_SELECTED)); /* Left column */ - /* Use context section */ + /* Use context section */ List list = new List(new CategoryUseContextModelBuilder()); list.setSelectionModel(m_contextModel); list.addChangeListener(new ContextSelectionListener()); /* Category tree section */ - m_categoryTree = new BaseTree(new CategoryTreeModelBuilder(m_contextModel)); + m_categoryTree = new BaseTree(new CategoryTreeModelBuilder( + m_contextModel)); m_categoryTree.addChangeListener(new SelectionListener()); m_model = m_categoryTree.getSelectionModel(); @@ -87,11 +101,12 @@ public final class CategoryAdminPane extends BaseAdminPane { contextGroup.setSubject(list); final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final PermissionChecker permissionChecker = cdiUtil.findBean(PermissionChecker.class); + final PermissionChecker permissionChecker = cdiUtil.findBean( + PermissionChecker.class); if (permissionChecker.isPermitted(AdminPrivileges.ADMINISTER_CATEGORIES)) { ActionLink addContextAction = new ActionLink(new Label(gz( - "cms.ui.category.add_use_context"))); + "cms.ui.category.add_use_context"))); Form addContextForm = new AddUseContextForm(m_contextModel); getBody().add(addContextForm); getBody().connect(addContextAction, addContextForm); @@ -119,8 +134,9 @@ public final class CategoryAdminPane extends BaseAdminPane { setEdit(gz("cms.ui.category.edit"), new CategoryEditForm(m_parent, m_category)); - setDelete(new DeleteLink(new Label(gz("cms.ui.category.delete"))), new DeleteForm( - new SimpleContainer())); + setDelete(new DeleteLink(new Label(gz("cms.ui.category.delete"))), + new DeleteForm( + new SimpleContainer())); setIntroPane(new Label(gz("cms.ui.category.intro"))); setItemPane(new CategoryItemPane(m_model, @@ -157,7 +173,6 @@ public final class CategoryAdminPane extends BaseAdminPane { //String context = getUseContext(state); //boolean isDefaultContext = // (context == null) || DEFAULT_USE_CONTEXT.equals(context); - //if (cat.isRoot() || !cat.getChildren().isEmpty()) { // m_alternativeLabel.generateXML(state, parent); //} else { @@ -175,8 +190,7 @@ public final class CategoryAdminPane extends BaseAdminPane { Label catLabel = new Label(); catLabel.addPrintListener(pe -> { Label label = (Label) pe.getTarget(); - Category cat = - m_category.getCategory(pe.getPageState()); + Category cat = m_category.getCategory(pe.getPageState()); java.util.List descendants = cat.getSubCategories(); java.util.List catObjects = cat.getObjects(); @@ -191,7 +205,8 @@ public final class CategoryAdminPane extends BaseAdminPane { sb.append(" descendant object(s). "); } if (descendants.size() > 0 || catObjects.size() > 0) { - sb.append("Descendants will be orphaned, if this category is removed."); + sb.append( + "Descendants will be orphaned, if this category is removed."); } label.setLabel(gz(sb.toString())); }); @@ -200,11 +215,13 @@ public final class CategoryAdminPane extends BaseAdminPane { @Override public final void process(final FormSectionEvent e) - throws FormProcessException { + throws FormProcessException { final PageState state = e.getPageState(); final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final PermissionChecker permissionChecker = cdiUtil.findBean(PermissionChecker.class); - final CategoryRepository repository = cdiUtil.findBean(CategoryRepository.class); + final PermissionChecker permissionChecker = cdiUtil.findBean( + PermissionChecker.class); + final CategoryRepository repository = cdiUtil.findBean( + CategoryRepository.class); final Category category = m_category.getCategory(state); if (category == null) { return; @@ -214,7 +231,8 @@ public final class CategoryAdminPane extends BaseAdminPane { // category, // Kernel.getContext(). // getParty())); - permissionChecker.checkPermission(AdminPrivileges.ADMINISTER_CATEGORIES, category); + permissionChecker.checkPermission( + AdminPrivileges.ADMINISTER_CATEGORIES, category); // if (category.isRoot()) { // Category root = @@ -226,8 +244,8 @@ public final class CategoryAdminPane extends BaseAdminPane { // } // m_contextModel.setSelectedKey(state, DEFAULT_USE_CONTEXT); // } else { - Category parent = category.getParentCategory(); - m_model.setSelectedKey(state, parent.getUniqueId()); + Category parent = category.getParentCategory(); + m_model.setSelectedKey(state, parent.getUniqueId()); // } //category.deleteCategoryAndOrphan(); @@ -242,7 +260,8 @@ public final class CategoryAdminPane extends BaseAdminPane { protected final Object initialValue(final PageState state) { final String id = m_model.getSelectedKey(state).toString(); final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final CategoryRepository repository = cdiUtil.findBean(CategoryRepository.class); + final CategoryRepository repository = cdiUtil.findBean( + CategoryRepository.class); if (id == null) { return null; } else { @@ -277,7 +296,6 @@ public final class CategoryAdminPane extends BaseAdminPane { // } // // } - private class UseContextSelectionModel extends ParameterSingleSelectionModel { public UseContextSelectionModel(ParameterModel m) { @@ -304,15 +322,26 @@ public final class CategoryAdminPane extends BaseAdminPane { public class ContextSelectionListener implements ChangeListener { - public final void stateChanged(final ChangeEvent e) { - LOGGER.debug("Selection state changed; I may change " + "the body's visible pane"); + public final void stateChanged(final ChangeEvent event) { + LOGGER.debug("Selection state changed; I may change " + + "the body's visible pane"); - final PageState state = e.getPageState(); + final PageState state = event.getPageState(); getBody().reset(state); if (m_contextModel.isSelected(state)) { - final Category root = (Category) m_contextModel.getSelectedKey(state); + + final String rootCategoryId = (String) m_contextModel + .getSelectedKey(state); + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final CategoryRepository categoryRepo = cdiUtil + .findBean(CategoryRepository.class); + final Category root = categoryRepo + .findById(Long.parseLong(rootCategoryId)) + .orElseThrow(() -> new UnexpectedErrorException(String + .format("No Category with ID %s in the database.", + rootCategoryId))); if (root != null) { m_model.setSelectedKey(state, root.getUniqueId()); @@ -321,11 +350,13 @@ public final class CategoryAdminPane extends BaseAdminPane { } if (m_model.isSelected(state)) { - LOGGER.debug("The selection model is selected; displaying " + "the item pane"); + LOGGER.debug("The selection model is selected; displaying " + + "the item pane"); getBody().push(state, getItemPane()); } } } + } diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/pagemodel/ItemListComponentForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/pagemodel/ItemListComponentForm.java index 20ab0ae3c..12cd221bc 100644 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/pagemodel/ItemListComponentForm.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/pagemodel/ItemListComponentForm.java @@ -41,7 +41,7 @@ import java.util.stream.Collectors; /** * Form for adding/editing a {@link ItemListComponent}. - * + * * @author Jens Pelzetter */ public class ItemListComponentForm @@ -109,32 +109,29 @@ public class ItemListComponentForm final PageState state, final FormData data) { - final Object[] descendingValues = (Object[]) data.get(DESCENDING); + final Object[] descendingValues = (Object[]) data.get(DESCENDING_BOX); final String limitToTypeValue = data.getString(LIMIT_TO_TYPE); final String pageSizeValue = data.getString(PAGE_SIZE); final String listOrderValue = data.getString(LIST_ORDER); - final boolean descendingValue; - if (descendingValues != null - && descendingValues.length != 0 - && DESCENDING.equals(descendingValues[0])) { - - descendingValue = true; - } else { - descendingValue = false; - } - + final boolean descendingValue = isDescending(descendingValues); final List listOrder = Arrays .stream(listOrderValue.split("\n")) .collect(Collectors.toList()); componentModel.setDescending(descendingValue); - componentModel.setLimitToTypes(limitToTypeValue); + componentModel.setLimitToType(limitToTypeValue); componentModel.setPageSize(Integer.parseInt(pageSizeValue)); componentModel.setListOrder(listOrder); } + private boolean isDescending(final Object[] descendingValues) { + return descendingValues != null + && descendingValues.length != 0 + && DESCENDING.equals(descendingValues[0]); + } + @Override public void init(final FormSectionEvent event) throws FormProcessException { @@ -145,21 +142,23 @@ public class ItemListComponentForm final ItemListComponent component = getComponentModel(); - final Object[] descendingValue; - if (component.isDescending()) { - descendingValue = new Object[]{DESCENDING}; - } else { - descendingValue = new Object[]{}; + if (component != null) { + final Object[] descendingValue; + if (component.isDescending()) { + descendingValue = new Object[]{DESCENDING}; + } else { + descendingValue = new Object[]{}; + } + descendingBox.setValue(state, descendingValue); + + limitToTypeField.setValue(state, component.getLimitToType()); + + pageSizeField.setValue(state, Integer.toString(component + .getPageSize())); + + listOrderArea.setValue(state, + String.join("\n", component.getListOrder())); } - descendingBox.setValue(state, descendingValue); - - limitToTypeField.setValue(state, component.getLimitToType()); - - pageSizeField.setValue(state, Integer.toString(component.getPageSize())); - - listOrderArea.setValue(state, - String.join("\n", component.getListOrder())); - } @Override @@ -186,4 +185,5 @@ public class ItemListComponentForm } } } + } diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/pages/PagesAdminPage.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/pages/PagesAdminPage.java index 248587e61..8384bc502 100644 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/pages/PagesAdminPage.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/pages/PagesAdminPage.java @@ -21,7 +21,6 @@ package com.arsdigita.cms.ui.pages; import com.arsdigita.bebop.BoxPanel; import com.arsdigita.bebop.Form; import com.arsdigita.bebop.FormData; -import com.arsdigita.bebop.FormModel; import com.arsdigita.bebop.FormProcessException; import com.arsdigita.bebop.Label; import com.arsdigita.bebop.Page; @@ -33,7 +32,6 @@ import com.arsdigita.bebop.Text; import com.arsdigita.bebop.Tree; import com.arsdigita.bebop.event.ActionEvent; import com.arsdigita.bebop.event.ChangeEvent; -import com.arsdigita.bebop.event.ChangeListener; import com.arsdigita.bebop.event.FormSectionEvent; import com.arsdigita.bebop.event.PrintEvent; import com.arsdigita.bebop.form.Option; @@ -241,7 +239,7 @@ public class PagesAdminPage extends Page { final PageModelRepository pageModelRepo = cdiUtil .findBean(PageModelRepository.class); final List pageModels = pageModelRepo - .findByApplication(pagesInstance); + .findDraftByApplication(pagesInstance); final GlobalizationHelper globalizationHelper = cdiUtil .findBean(GlobalizationHelper.class); diff --git a/ccm-cms/src/main/java/org/librecms/Cms.java b/ccm-cms/src/main/java/org/librecms/Cms.java index 7a15c87d0..4f9e7abf0 100644 --- a/ccm-cms/src/main/java/org/librecms/Cms.java +++ b/ccm-cms/src/main/java/org/librecms/Cms.java @@ -87,6 +87,7 @@ import java.util.Properties; instanceForm = ApplicationInstanceForm.class, settingsPane = SettingsPane.class, descBundle = CmsConstants.CMS_BUNDLE, + titleKey = "pages_application.title", creator = PagesCreator.class, servletPath = "/templates/servlet/pages" ) diff --git a/ccm-cms/src/main/java/org/librecms/pagemodel/ItemListComponent.java b/ccm-cms/src/main/java/org/librecms/pagemodel/ItemListComponent.java index 7833ea8a5..7d1b12993 100644 --- a/ccm-cms/src/main/java/org/librecms/pagemodel/ItemListComponent.java +++ b/ccm-cms/src/main/java/org/librecms/pagemodel/ItemListComponent.java @@ -79,6 +79,10 @@ public class ItemListComponent extends ComponentModel { @Column(name = "LIST_ORDER") private List listOrder; + public ItemListComponent() { + listOrder = new ArrayList<>(); + } + public boolean isDescending() { return descending; } @@ -91,7 +95,7 @@ public class ItemListComponent extends ComponentModel { return limitToType; } - public void setLimitToTypes(final String limitToType) { + public void setLimitToType(final String limitToType) { this.limitToType = limitToType; } diff --git a/ccm-cms/src/main/resources/org/librecms/CmsResources.properties b/ccm-cms/src/main/resources/org/librecms/CmsResources.properties index a4e5a35c9..f5b79d227 100644 --- a/ccm-cms/src/main/resources/org/librecms/CmsResources.properties +++ b/ccm-cms/src/main/resources/org/librecms/CmsResources.properties @@ -495,3 +495,4 @@ cms.ui.pages.title=Administer pages cms.ui.pages.page_config_for_category=Page Configuration for category {0} cms.ui.pages.assigned_page_model.inherit=Inherit from parent cms.ui.pages.no_category_selected=No category selected +pages_application.title=Pages diff --git a/ccm-cms/src/main/resources/org/librecms/CmsResources_de.properties b/ccm-cms/src/main/resources/org/librecms/CmsResources_de.properties index db147d26c..dbe8ea021 100644 --- a/ccm-cms/src/main/resources/org/librecms/CmsResources_de.properties +++ b/ccm-cms/src/main/resources/org/librecms/CmsResources_de.properties @@ -492,3 +492,4 @@ cms.ui.pages.title=Seitenbaum verwalten cms.ui.pages.page_config_for_category=Seiten-Konfiguration f\u00fcr Kategorie {0} cms.ui.pages.assigned_page_model.inherit=PageModel der \u00fcbergeordneten Seite verwenden cms.ui.pages.no_category_selected=Keine Kategorie ausgew\u00e4hlt +pages_application.title=Pages diff --git a/ccm-cms/src/main/resources/org/librecms/CmsResources_fr.properties b/ccm-cms/src/main/resources/org/librecms/CmsResources_fr.properties index 755233ebf..12faa82b2 100644 --- a/ccm-cms/src/main/resources/org/librecms/CmsResources_fr.properties +++ b/ccm-cms/src/main/resources/org/librecms/CmsResources_fr.properties @@ -451,3 +451,4 @@ cms.ui.pages.title=Administer pages cms.ui.pages.page_config_for_category=Page Configuration for category {0} cms.ui.pages.assigned_page_model.inherit=Inherit from parent cms.ui.pages.no_category_selected=No category selected +pages_application.title=Pages diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/pagemodels/PageModelDetails.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/pagemodels/PageModelDetails.java index 6b0e7e7ee..cafe05f7d 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/admin/pagemodels/PageModelDetails.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/pagemodels/PageModelDetails.java @@ -26,7 +26,7 @@ import com.arsdigita.bebop.Label; import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.ParameterSingleSelectionModel; import com.arsdigita.bebop.PropertySheet; -import com.arsdigita.bebop.event.FormProcessListener; +import com.arsdigita.bebop.event.ActionEvent; import com.arsdigita.bebop.event.FormSectionEvent; import com.arsdigita.bebop.event.PrintEvent; import com.arsdigita.bebop.event.PrintListener; @@ -42,6 +42,7 @@ import org.libreccm.pagemodel.ComponentModel; import org.libreccm.pagemodel.ComponentModels; import org.libreccm.pagemodel.PageModel; import org.libreccm.pagemodel.PageModelComponentModel; +import org.libreccm.pagemodel.PageModelManager; import org.libreccm.pagemodel.PageModelRepository; import java.util.List; @@ -55,6 +56,10 @@ import java.util.TooManyListenersException; */ class PageModelDetails extends BoxPanel { + private final PageModelsTab pageModelTab; + private final ParameterSingleSelectionModel selectedModelId; + private final ParameterSingleSelectionModel selectedComponentId; + public PageModelDetails( final PageModelsTab pageModelTab, final ParameterSingleSelectionModel selectedModelId, @@ -62,6 +67,10 @@ class PageModelDetails extends BoxPanel { super(BoxPanel.VERTICAL); + this.pageModelTab = pageModelTab; + this.selectedModelId = selectedModelId; + this.selectedComponentId = selectedComponentId; + final ActionLink backLink = new ActionLink(new GlobalizedMessage( "ui.admin.pagemodels.details.back", AdminUiConstants.ADMIN_BUNDLE)); @@ -74,20 +83,7 @@ class PageModelDetails extends BoxPanel { final Label heading = new Label(); heading.setClassAttr("heading"); - heading.addPrintListener(event -> { - final PageState state = event.getPageState(); - final Label target = (Label) event.getTarget(); - final PageModelRepository pageModelRepo = CdiUtil - .createCdiUtil() - .findBean(PageModelRepository.class); - final PageModel pageModel = pageModelRepo - .findById(Long.parseLong(selectedModelId.getSelectedKey(state))) - .get(); - target.setLabel(new GlobalizedMessage( - "ui.admin.pagemodels.details.heading", - AdminUiConstants.ADMIN_BUNDLE, - new String[]{pageModel.getName()})); - }); + heading.addPrintListener(this::printHeading); super.add(heading); final PropertySheet propertySheet = new PropertySheet( @@ -100,7 +96,16 @@ class PageModelDetails extends BoxPanel { editProperties.addActionListener(event -> { pageModelTab.showPageModelForm(event.getPageState()); }); - super.add(editProperties); + + final ActionLink publishLink = new ActionLink(new GlobalizedMessage( + "ui.admin.pagemodels.details.publish", + AdminUiConstants.ADMIN_BUNDLE)); + publishLink.addActionListener(this::publishPageModel); + + final BoxPanel actionsPanel = new BoxPanel(BoxPanel.HORIZONTAL); + actionsPanel.add(editProperties); + actionsPanel.add(publishLink); + super.add(actionsPanel); final AddComponentForm addComponentForm = new AddComponentForm( pageModelTab); @@ -112,13 +117,49 @@ class PageModelDetails extends BoxPanel { super.add(componentsTable); } + private void printHeading(final PrintEvent event) { + final PageState state = event.getPageState(); + final Label target = (Label) event.getTarget(); + final PageModelRepository pageModelRepo = CdiUtil + .createCdiUtil() + .findBean(PageModelRepository.class); + final PageModel pageModel = pageModelRepo + .findById(Long.parseLong(selectedModelId.getSelectedKey(state))) + .get(); + target.setLabel(new GlobalizedMessage( + "ui.admin.pagemodels.details.heading", + AdminUiConstants.ADMIN_BUNDLE, + new String[]{pageModel.getName()})); + } + + private void publishPageModel(final ActionEvent event) { + + final PageState state = event.getPageState(); + + final String selectedPageModelIdStr = selectedModelId + .getSelectedKey(state); + + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final PageModelManager pageModelManager = cdiUtil + .findBean(PageModelManager.class); + final PageModelRepository pageModelRepo = cdiUtil + .findBean(PageModelRepository.class); + + final PageModel pageModel = pageModelRepo + .findById(Long.parseLong(selectedPageModelIdStr)) + .orElseThrow(() -> new UnexpectedErrorException(String + .format("No PageModel with ID %s in the database.", + selectedPageModelIdStr))); + + final PageModel draftModel = pageModelManager.getDraftVersion(pageModel); + pageModelManager.publish(draftModel); + } + /** * Form for selecting the type of {@link ComponentModel} to add to the * {@link PageModel}. */ - private class AddComponentForm - extends Form - implements FormProcessListener { + private class AddComponentForm extends Form { private final PageModelsTab pageModelTab; private final SingleSelect selectType; @@ -152,10 +193,9 @@ class PageModelDetails extends BoxPanel { AdminUiConstants.ADMIN_BUNDLE)); super.add(submit); - super.addProcessListener(this); + super.addProcessListener(this::process); } - @Override public void process(final FormSectionEvent event) throws FormProcessException { diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/pagemodels/PageModelsController.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/pagemodels/PageModelsController.java index abfb88a06..a910738f8 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/admin/pagemodels/PageModelsController.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/pagemodels/PageModelsController.java @@ -82,7 +82,7 @@ class PageModelsController implements Serializable { protected List findPageModels() { return pageModelRepo - .findAll() + .findAllDraftModels() .stream() .map(this::buildRow) .sorted() @@ -109,7 +109,7 @@ class PageModelsController implements Serializable { applicationId))); return !pageModelRepo - .findByApplicationAndName(application, name) + .findLiveByApplicationAndName(application, name) .isPresent(); } diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/ApplicationTreeDataProvider.java b/ccm-core/src/main/java/org/libreccm/admin/ui/ApplicationTreeDataProvider.java index 7d0d12503..f4b113275 100644 --- a/ccm-core/src/main/java/org/libreccm/admin/ui/ApplicationTreeDataProvider.java +++ b/ccm-core/src/main/java/org/libreccm/admin/ui/ApplicationTreeDataProvider.java @@ -23,6 +23,7 @@ import com.vaadin.data.provider.AbstractBackEndHierarchicalDataProvider; import com.vaadin.data.provider.HierarchicalQuery; import org.libreccm.core.UnexpectedErrorException; import org.libreccm.l10n.GlobalizationHelper; +import org.libreccm.l10n.LocalizedTextsUtil; import org.libreccm.web.ApplicationManager; import org.libreccm.web.ApplicationRepository; import org.libreccm.web.ApplicationType; @@ -99,10 +100,10 @@ class ApplicationTreeDataProvider private ApplicationTreeNode buildApplicationTreeNode( final ApplicationType type) { - final ResourceBundle bundle = ResourceBundle - .getBundle(type.descBundle()); + final LocalizedTextsUtil textsUtil = globalizationHelper + .getLocalizedTextsUtil(type.descBundle()); - final String title = bundle.getString(type.titleKey()); + final String title = textsUtil.getText(type.titleKey()); final ApplicationTreeNode node = new ApplicationTreeNode(); node.setTitle(title); @@ -155,8 +156,18 @@ class ApplicationTreeDataProvider node.setNodeId(application.getUuid()); node.setNodeType(ApplicationTreeNodeType.APPLICATION_NODE); - node.setTitle(globalizationHelper - .getValueFromLocalizedString(application.getTitle())); + final String title; + if (globalizationHelper + .getValueFromLocalizedString(application.getTitle()) == null + || globalizationHelper + .getValueFromLocalizedString(application.getTitle()).isEmpty()) { + + title = application.getPrimaryUrl(); + } else { + title =globalizationHelper + .getValueFromLocalizedString(application.getTitle()); + } + node.setTitle(title); return node; } diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/PageModelsTab.java b/ccm-core/src/main/java/org/libreccm/admin/ui/PageModelsTab.java index c8810d4cc..55f935bc7 100644 --- a/ccm-core/src/main/java/org/libreccm/admin/ui/PageModelsTab.java +++ b/ccm-core/src/main/java/org/libreccm/admin/ui/PageModelsTab.java @@ -26,6 +26,7 @@ import com.vaadin.ui.Component; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.Grid; import com.vaadin.ui.HorizontalSplitPanel; +import com.vaadin.ui.Label; import com.vaadin.ui.Tree; import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; @@ -33,9 +34,6 @@ import com.vaadin.ui.themes.ValoTheme; import org.libreccm.l10n.LocalizedTextsUtil; import org.libreccm.pagemodel.PageModel; import org.libreccm.ui.ConfirmDialog; -import org.libreccm.web.CcmApplication; - -import java.util.concurrent.Callable; /** * @@ -59,8 +57,8 @@ class PageModelsTab extends CustomComponent { final Tree applicationTree = new Tree<>( adminViewController.getApplicationTreeDataProvider()); - applicationTree.addItemClickListener(event -> { - }); + applicationTree.setItemCaptionGenerator(ApplicationTreeNode::getTitle); + applicationTree.setItemCollapseAllowedProvider(node -> { return !node.getNodeType().equals(ApplicationTreeNodeType.ROOT_NODE); }); @@ -102,9 +100,27 @@ class PageModelsTab extends CustomComponent { adminViewController)) .setId(COL_DELETE); - super.setCompositionRoot(new HorizontalSplitPanel(applicationTree, - pageModelsGrid)); + pageModelsGrid.setVisible(false); + final Label placeholder = new Label(localizedTextsUtil.getText( + "ui.admin.pagemodels.select_application")); + + final VerticalLayout layout = new VerticalLayout(pageModelsGrid, + placeholder); + + applicationTree.addItemClickListener(event -> { + final PageModelsTableDataProvider dataProvider + = (PageModelsTableDataProvider) pageModelsGrid + .getDataProvider(); + dataProvider.setApplicationUuid(event.getItem().getNodeId()); + pageModelsGrid.setVisible(true); + placeholder.setVisible(false); + }); + + final HorizontalSplitPanel panel = new HorizontalSplitPanel( + applicationTree, layout); + panel.setSplitPosition(33.0f); + super.setCompositionRoot(panel); } private Component buildEditButton(final PageModelsTableRow row, diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/PageModelsTableDataProvider.java b/ccm-core/src/main/java/org/libreccm/admin/ui/PageModelsTableDataProvider.java index 051c668e6..c4ad435ca 100644 --- a/ccm-core/src/main/java/org/libreccm/admin/ui/PageModelsTableDataProvider.java +++ b/ccm-core/src/main/java/org/libreccm/admin/ui/PageModelsTableDataProvider.java @@ -21,10 +21,12 @@ package org.libreccm.admin.ui; import com.vaadin.cdi.ViewScoped; import com.vaadin.data.provider.AbstractBackEndDataProvider; import com.vaadin.data.provider.Query; +import org.libreccm.core.UnexpectedErrorException; import org.libreccm.l10n.GlobalizationHelper; import org.libreccm.pagemodel.PageModel; import org.libreccm.pagemodel.PageModelManager; import org.libreccm.pagemodel.PageModelVersion; +import org.libreccm.web.ApplicationRepository; import org.libreccm.web.CcmApplication; import java.util.stream.Stream; @@ -46,6 +48,9 @@ class PageModelsTableDataProvider private static final long serialVersionUID = 8052894182508842905L; + @Inject + private ApplicationRepository applicationRepo; + @Inject private EntityManager entityManager; @@ -65,6 +70,16 @@ class PageModelsTableDataProvider this.application = application; refreshAll(); } + + @Transactional(Transactional.TxType.REQUIRED) + public void setApplicationUuid(final String uuid) { + application = applicationRepo + .findByUuid(uuid) + .orElseThrow(() -> new UnexpectedErrorException(String + .format("No Application with UUID %s in the database.", + uuid))); + refreshAll(); + } @Transactional(Transactional.TxType.REQUIRED) @Override @@ -86,8 +101,8 @@ class PageModelsTableDataProvider .and(builder.equal(from.get("application"), application), builder.equal(from.get("version"), PageModelVersion.DRAFT))) - .orderBy(builder.asc(from.get("name"))) - .orderBy(builder.asc(from.get("title"))); + .orderBy(builder.asc(from.get("name"))); +// .orderBy(builder.asc(from.get("title"))); return entityManager .createQuery(criteriaQuery) diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/PageModel.java b/ccm-core/src/main/java/org/libreccm/pagemodel/PageModel.java index 38cea1aeb..3abeec12d 100644 --- a/ccm-core/src/main/java/org/libreccm/pagemodel/PageModel.java +++ b/ccm-core/src/main/java/org/libreccm/pagemodel/PageModel.java @@ -50,8 +50,9 @@ import javax.persistence.OneToMany; import javax.persistence.Table; /** - * A {@link PageModel} is used by a {@link PageRenderer} implementation to render - * a page. The {@code PageModel} specifics which components are used on a page. + * A {@link PageModel} is used by a {@link PageRenderer} implementation to + * render a page. The {@code PageModel} specifics which components are used on a + * page. * * @author Jens Pelzetter * @@ -63,6 +64,16 @@ import javax.persistence.Table; @Inheritance(strategy = InheritanceType.JOINED) @Table(name = "PAGE_MODELS", schema = CoreConstants.DB_SCHEMA) @NamedQueries({ + @NamedQuery( + name = "PageModel.findAllDraftModels", + query = "SELECT p FROM PageModel p " + + "WHERE p.version = org.libreccm.pagemodel.PageModelVersion.DRAFT") + , + @NamedQuery( + name = "PageModel.findAllLiveModels", + query = "SELECT p FROM PageModel p " + + "WHERE p.version = org.libreccm.pagemodel.PageModelVersion.LIVE") + , @NamedQuery( name = "PageModel.findDraftVersion", query = "SELECT p FROM PageModel p " @@ -84,19 +95,47 @@ import javax.persistence.Table; + "AND p.version = org.libreccm.pagemodel.PageModelVersion.LIVE") , @NamedQuery( - name = "PageModel.findByApplication", + name = "PageModel.findDraftByApplication", + query = "SELECT p FROM PageModel p " + + "WHERE p.application = :application " + + "AND p.version = org.libreccm.pagemodel.PageModelVersion.DRAFT" + ) + , + @NamedQuery( + name = "PageModel.findDraftByApplicationAndName", + query = "SELECT p FROM PageModel p " + + "WHERE p.application = :application " + + "AND p.version = org.libreccm.pagemodel.PageModelVersion.DRAFT" + ) + , + @NamedQuery( + name = "PageModel.countDraftByApplicationAndName", + query = "SELECT COUNT(p) FROM PageModel p " + + "WHERE p.application = :application " + + "AND p.version = org.libreccm.pagemodel.PageModelVersion.DRAFT" + ) + , + @NamedQuery( + name = "PageModel.countDraftByApplication", + query = "SELECT COUNT(p) FROM PageModel p " + + "WHERE p.application = :application " + + "AND p.version = org.libreccm.pagemodel.PageModelVersion.DRAFT" + ) + , + @NamedQuery( + name = "PageModel.findLiveByApplication", query = "SELECT p FROM PageModel p " + "WHERE p.application = :application " + "AND p.version = org.libreccm.pagemodel.PageModelVersion.LIVE") , @NamedQuery( - name = "PageModel.countByApplication", + name = "PageModel.countLiveByApplication", query = "SELECT COUNT(p) FROM PageModel p " + "WHERE p.application = :application " + "AND p.version = org.libreccm.pagemodel.PageModelVersion.LIVE") , @NamedQuery( - name = "PageModel.findByApplicationAndName", + name = "PageModel.findLiveByApplicationAndName", query = "SELECT p FROM PageModel p " + "WHERE p.name = :name " + "AND p.application = :application " @@ -104,7 +143,7 @@ import javax.persistence.Table; ) , @NamedQuery( - name = "PageModel.countByApplicationAndName", + name = "PageModel.countLiveByApplicationAndName", query = "SELECT COUNT(p) FROM PageModel p " + "WHERE p.name = :name " + "AND p.application = :application " @@ -206,6 +245,7 @@ public class PageModel implements Serializable { public PageModel() { title = new LocalizedString(); description = new LocalizedString(); + components = new ArrayList<>(); } public long getPageModelId() { diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/PageModelManager.java b/ccm-core/src/main/java/org/libreccm/pagemodel/PageModelManager.java index 83240e126..47e69d6c8 100644 --- a/ccm-core/src/main/java/org/libreccm/pagemodel/PageModelManager.java +++ b/ccm-core/src/main/java/org/libreccm/pagemodel/PageModelManager.java @@ -46,6 +46,7 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.ServiceLoader; import java.util.Set; @@ -114,7 +115,7 @@ public class PageModelManager { /** * Creates a new {@link PageModel} for the provided application. The method * tries to retrieve the appropriate application by using - * {@link PageModelRepository#findByApplicationAndName(org.libreccm.web.CcmApplication, java.lang.String)}. + * {@link PageModelRepository#findLiveByApplicationAndName(org.libreccm.web.CcmApplication, java.lang.String)}. * Please note that this method will always return the * draft * version of the page model. @@ -134,23 +135,24 @@ public class PageModelManager { final CcmApplication application, final String type) { - if (application == null) { + Objects.requireNonNull(application, + "Can't create a page model for application null"); + Objects.requireNonNull(name, "Then name of a Pagemodel can't be null."); + if (name.isEmpty() + || name.matches("\\s*")) { throw new IllegalArgumentException( - "Can't create a page model for application null"); + "The name of a PageModel can't be empty."); } - if (name == null || name.trim().isEmpty()) { - throw new IllegalArgumentException( - "The name of a page model can't be null or empty."); - } LOGGER.debug( "Creating new PageModel with name \"{}\" for application \"{}\" and type \"{}\".", name, application.getPrimaryUrl(), type); - final long count = pageModelRepo.countByApplicationAndName(application, - name); + final long count = pageModelRepo.countLiveByApplicationAndName( + application, + name); if (count > 0) { LOGGER.error("A page model with the name \"{}\" for the " @@ -257,6 +259,11 @@ public class PageModelManager { @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) @Transactional(Transactional.TxType.REQUIRED) public PageModel publish(final PageModel pageModel) { + + Objects.requireNonNull(pageModel, "Can't publish PageModel null."); + + LOGGER.debug("Publishing PageModel \"{}\"...", pageModel.getName()); + final PageModel draftModel = getDraftVersion(pageModel); final PageModel liveModel; @@ -266,6 +273,7 @@ public class PageModelManager { liveModel = new PageModel(); } + liveModel.setName(draftModel.getName()); liveModel.setVersion(PageModelVersion.LIVE); liveModel.setModelUuid(draftModel.getModelUuid()); @@ -274,7 +282,7 @@ public class PageModelManager { liveModel.getTitle().addValue(entry.getKey(), entry.getValue()); } - for (Map.Entry entry : liveModel.getDescription() + for (Map.Entry entry : draftModel.getDescription() .getValues().entrySet()) { liveModel.getDescription().addValue(entry.getKey(), entry.getValue()); @@ -283,12 +291,16 @@ public class PageModelManager { liveModel.setApplication(draftModel.getApplication()); liveModel.setType(draftModel.getType()); + LOGGER.debug("Publishing ComponentModels of PageModel \"{}\"...", + draftModel.getName()); liveModel.clearComponents(); for (final ComponentModel draft : draftModel.getComponents()) { final ComponentModel live = publishComponentModel(draft); addComponentModel(liveModel, live); } + LOGGER.debug("Successfully published PageModel \"{}\".", + liveModel.getName()); return liveModel; } @@ -304,6 +316,11 @@ public class PageModelManager { @SuppressWarnings("unchecked") private ComponentModel publishComponentModel(final ComponentModel draftModel) { + Objects.requireNonNull(draftModel, "Can't publish ComponentModel null."); + + LOGGER.debug("Publishing ComponentModel \"{}\"...", + draftModel.getKey()); + final Class clazz = draftModel.getClass(); final ComponentModel liveModel; @@ -324,6 +341,12 @@ public class PageModelManager { for (final PropertyDescriptor propertyDescriptor : beanInfo. getPropertyDescriptors()) { + + LOGGER.debug( + "Publishing property \"{}\" of ComponentModel \"{}\"...", + propertyDescriptor.getName(), + draftModel.getKey()); + final Class propType = propertyDescriptor.getPropertyType(); final Method readMethod = propertyDescriptor.getReadMethod(); final Method writeMethod = propertyDescriptor.getWriteMethod(); @@ -339,18 +362,18 @@ public class PageModelManager { if (propType != null && propType.isAssignableFrom(List.class)) { - final List source; - final List target; try { - source = (List) readMethod.invoke(draftModel); - target = (List) readMethod.invoke(liveModel); + final List source = (List) readMethod + .invoke(draftModel); + final List target = new ArrayList<>(); + target.addAll(source); + writeMethod.invoke(draftModel, target); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { throw new UnexpectedErrorException(ex); } - target.addAll(source); } else if (propType != null && propType.isAssignableFrom(Map.class)) { @@ -399,6 +422,8 @@ public class PageModelManager { componentModelRepo.save(liveModel); + LOGGER.debug("Successfully published ComponentModel \"{}\".", + liveModel.getKey()); return liveModel; } @@ -413,6 +438,7 @@ public class PageModelManager { */ private boolean propertyIsExcluded(final String name) { final String[] excluded = new String[]{ + "class", "uuid", "modelUuid" }; diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/PageModelRepository.java b/ccm-core/src/main/java/org/libreccm/pagemodel/PageModelRepository.java index 7b8bf2075..9d530cf4e 100644 --- a/ccm-core/src/main/java/org/libreccm/pagemodel/PageModelRepository.java +++ b/ccm-core/src/main/java/org/libreccm/pagemodel/PageModelRepository.java @@ -27,7 +27,9 @@ import org.libreccm.web.CcmApplication; import javax.enterprise.context.RequestScoped; import javax.persistence.TypedQuery; import javax.transaction.Transactional; + import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.UUID; @@ -39,6 +41,8 @@ import java.util.UUID; @RequestScoped public class PageModelRepository extends AbstractEntityRepository { + private static final long serialVersionUID = -7240418542790568571L; + @Override public Class getEntityClass() { return PageModel.class; @@ -46,9 +50,8 @@ public class PageModelRepository extends AbstractEntityRepository findAllDraftModels() { + + final TypedQuery query = getEntityManager() + .createNamedQuery("PageModel.findAllDraftModels", PageModel.class); + + return query.getResultList(); + } + + /** + * Find all live versions of {@link PageModel}s. + * + * @return A list with all draft versions of {@link PageModel}s. + */ + @Transactional(Transactional.TxType.REQUIRED) + public List findAllLiveModels() { + + final TypedQuery query = getEntityManager() + .createNamedQuery("PageModel.findAllLiveModels", PageModel.class); + + return query.getResultList(); + } + + /** + * Finds the draft versions of all {@link PageModel}s for the provided * application. * * @param application The application for which the {@link PageModel}s are * retrieved. * - * @return A list of the {@link PageModel}s defined for the provided { - * - * @coded application}. + * @return A list of the {@link PageModel}s defined for the provided + * {@code application}. */ - public List findByApplication(final CcmApplication application) { - if (application == null) { - throw new IllegalArgumentException( - "Can't find page models for application null"); - } + @Transactional(Transactional.TxType.REQUIRED) + @AuthorizationRequired + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + public List findDraftByApplication( + final CcmApplication application) { - final TypedQuery query = getEntityManager().createNamedQuery( - "PageModel.findByApplication", PageModel.class); + Objects.requireNonNull(application, + "Can't find page models for application null"); + + final TypedQuery query = getEntityManager() + .createNamedQuery("PageModel.findDraftByApplication", + PageModel.class); query.setParameter("application", application); return query.getResultList(); @@ -108,20 +143,22 @@ public class PageModelRepository extends AbstractEntityRepository query = getEntityManager().createNamedQuery( - "PageModel.countByApplication", Long.class); + "PageModel.countDraftByApplication", Long.class); query.setParameter("application", application); return query.getSingleResult(); @@ -140,27 +177,27 @@ public class PageModelRepository extends AbstractEntityRepository findByApplicationAndName( + public Optional findDraftByApplicationAndName( final CcmApplication application, final String name) { - if (application == null) { - throw new IllegalArgumentException( - "Can't find page models for application null"); - } + Objects.requireNonNull(application, + "Can't find page models for application null"); + Objects.requireNonNull(name, + "The name of a page model can't be null or empty."); - if (name == null || name.trim().isEmpty()) { + if (name.isEmpty() || name.matches("\\s*")) { throw new IllegalArgumentException( "The name of a page model can't be null or empty."); } - final long count = countByApplicationAndName(application, name); + final long count = countLiveByApplicationAndName(application, name); if (count == 0) { return Optional.empty(); } final TypedQuery query = getEntityManager().createNamedQuery( - "PageModel.findByApplicationAndName", PageModel.class); + "PageModel.findDraftByApplicationAndName", PageModel.class); query.setParameter("application", application); query.setParameter("name", name); @@ -178,21 +215,145 @@ public class PageModelRepository extends AbstractEntityRepository query = getEntityManager().createNamedQuery( - "PageModel.countByApplicationAndName", Long.class); + "PageModel.countDraftByApplicationAndName", Long.class); + query.setParameter("application", application); + query.setParameter("name", name); + + return query.getSingleResult(); + } + + /** + * Finds the live versions of all {@link PageModel}s for the provided + * application. + * + * @param application The application for which the {@link PageModel}s are + * retrieved. + * + * @return A list of the {@link PageModel}s defined for the provided + * {@code application}. + */ + @Transactional(Transactional.TxType.REQUIRED) + public List findLiveByApplication( + final CcmApplication application) { + + Objects.requireNonNull(application, + "Can't find page models for application null"); + + final TypedQuery query = getEntityManager() + .createNamedQuery("PageModel.findLiveByApplication", + PageModel.class); + query.setParameter("application", application); + + return query.getResultList(); + } + + /** + * Counts the {@link PageModel}s (live version) defined for a application. + * + * @param application The application for which the {@link PageModels}s are + * counted. + * + * @return The number of {@link PageModel}s defined for the provided + * {@code application}. + */ + @Transactional(Transactional.TxType.REQUIRED) + public long countLiveByApplication(final CcmApplication application) { + + Objects.requireNonNull(application, + "Can't count page models for application null"); + + final TypedQuery query = getEntityManager().createNamedQuery( + "PageModel.countLiveByApplication", Long.class); + query.setParameter("application", application); + + return query.getSingleResult(); + } + + /** + * Finds a {@link PageModel} (live version) by the application and its + * {@code name}. + * + * @param application The application for which the {@link PageModel} is + * defined. + * @param name The name of the {@link PageModel}. + * + * @return An {@link Optional} containing the {@link PageModel} for the + * provided {@code application} with the provided {@code name}. If + * there is no {@link PageModel} matching the criteria an empty + * {@link Optional} is returned. + */ + @Transactional(Transactional.TxType.REQUIRED) + public Optional findLiveByApplicationAndName( + final CcmApplication application, + final String name) { + + Objects.requireNonNull(application, + "Can't find page models for application null"); + Objects.requireNonNull(name, + "The name of a page model can't be null or empty."); + + if (name.isEmpty() || name.matches("\\s*")) { + throw new IllegalArgumentException( + "The name of a page model can't be null or empty."); + } + + final long count = countLiveByApplicationAndName(application, name); + if (count == 0) { + return Optional.empty(); + } + + final TypedQuery query = getEntityManager().createNamedQuery( + "PageModel.findLiveByApplicationAndName", PageModel.class); + query.setParameter("application", application); + query.setParameter("name", name); + + return Optional.of(query.getSingleResult()); + } + + /** + * Counts the number of {@link PageModel} (live version) defined for the + * provided application with the provided name. + * + * @param application The application for which the {@link PageModel} is + * defined. + * @param name The name of the {@link PageModel}. + * + * @return The number of {@link PageModel}s matching the criteria. Should be + * 0 or 1. + */ + @Transactional(Transactional.TxType.REQUIRED) + public long countLiveByApplicationAndName(final CcmApplication application, + final String name) { + + Objects.requireNonNull(application, + "Can't find page models for application null"); + Objects.requireNonNull(name, + "The name of a page model can't be null or empty."); + + if (name.isEmpty() || name.matches("\\s*")) { + throw new IllegalArgumentException( + "The name of a page model can't be null or empty."); + } + + final TypedQuery query = getEntityManager().createNamedQuery( + "PageModel.countLiveByApplicationAndName", Long.class); query.setParameter("application", application); query.setParameter("name", name); diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/ui/PageTreeModel.java b/ccm-core/src/main/java/org/libreccm/pagemodel/ui/PageTreeModel.java index 625e34093..b508db106 100644 --- a/ccm-core/src/main/java/org/libreccm/pagemodel/ui/PageTreeModel.java +++ b/ccm-core/src/main/java/org/libreccm/pagemodel/ui/PageTreeModel.java @@ -48,7 +48,7 @@ class PageTreeModel implements TreeModel { PageModelRepository.class); final CcmApplication application = ((ApplicationTreeNode) node) .getApplication(); - final long count = pageModelRepo.countByApplication(application); + final long count = pageModelRepo.countLiveByApplication(application); return count > 0; } else if (node instanceof PageModelTreeNode) { diff --git a/ccm-core/src/main/java/org/libreccm/sites/Site.java b/ccm-core/src/main/java/org/libreccm/sites/Site.java index b467707fd..addc324a1 100644 --- a/ccm-core/src/main/java/org/libreccm/sites/Site.java +++ b/ccm-core/src/main/java/org/libreccm/sites/Site.java @@ -54,7 +54,7 @@ import javax.persistence.Table; name = "Site.findDefaultSite", query = "SELECT s FROM Site s " + "WHERE s.defaultSite = true " - + "ORDER BY s.domain" + + "ORDER BY s.domainOfSite" ) , @NamedQuery( diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources.properties b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources.properties index 35d627505..09e321481 100644 --- a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources.properties +++ b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources.properties @@ -671,7 +671,7 @@ ui.admin.pagemodels.table.columns.headers.name=Name ui.admin.pagemodels.table.columns.headers.title=Title ui.admin.pagemodels.table.columns.headers.desc=Description ui.admin.pagemodels.table.columns.headers.remove=Delete -\ \tui.admin.pagemodels.table.columns.remove.label=Delete +\ ui.admin.pagemodels.table.columns.remove.label=Delete ui.admin.pagemodels.details.model_name=Name ui.admin.pagemodels.details.model_title=Titel ui.admin.pagemodels.details.model_application=Application @@ -680,3 +680,11 @@ ui.admin.pagemodels.details.edit_properties=Edit properties ui.admin.pagemodels.components.key.label=ID ui.admin.pagemodels.components.key.error.not_empty=The ID of a component can't be empty. ui.admin.pagemodels.table.columns.remove.label=Delete +ui.admin.pagemodels.details.publish=(Re-)Publish +ui.admin.users.table.filter.groupname.placeholder=Name of Group +ui.admin.users.table.filter.groupname.description=Filter groups by name +ui.admin.roles.table.description=Roles +ui.admin.users.table.filter.rolename.placeholder=Name of role +ui.admin.users.table.filter.rolename.description=Filter roles by name +ui.admin.pagemodels.table.columns.headers.islive=Is live? +ui.admin.pagemodels.select_application=Please select an application diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_de.properties b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_de.properties index f45f50472..c5b547046 100644 --- a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_de.properties +++ b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_de.properties @@ -675,7 +675,7 @@ ui.admin.pagemodels.table.columns.headers.name=Name ui.admin.pagemodels.table.columns.headers.title=Titel ui.admin.pagemodels.table.columns.headers.desc=Description ui.admin.pagemodels.table.columns.headers.remove=L\u00f6schen -\ \tui.admin.pagemodels.table.columns.remove.label=L\u00f6schen +\ ui.admin.pagemodels.table.columns.remove.label=L\u00f6schen ui.admin.pagemodels.details.model_name=Name ui.admin.pagemodels.details.model_title=Titel ui.admin.pagemodels.details.model_application=Applikation @@ -684,3 +684,11 @@ ui.admin.pagemodels.details.edit_properties=Bearbeiten ui.admin.pagemodels.components.key.label=ID ui.admin.pagemodels.components.key.error.not_empty=Die ID einer Komponente darf nicht leer sein. ui.admin.pagemodels.table.columns.remove.label=L\u00f6schen +ui.admin.pagemodels.details.publish=(Re-)Publizieren +ui.admin.users.table.filter.groupname.placeholder=Name der Gruppe +ui.admin.users.table.filter.groupname.description=Gruppen anhand des Namens filtern +ui.admin.roles.table.description=Rollen +ui.admin.users.table.filter.rolename.placeholder=Name der Rolle +ui.admin.users.table.filter.rolename.description=Rollen nach Name filtern +ui.admin.pagemodels.table.columns.headers.islive=Ist publiziert? +ui.admin.pagemodels.select_application=Bitte eine Applikation ausw\u00e4hlen diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_en.properties b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_en.properties index 46d0ae50d..04274acdc 100755 --- a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_en.properties +++ b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_en.properties @@ -668,7 +668,7 @@ ui.admin.pagemodels.table.columns.headers.name=Name ui.admin.pagemodels.table.columns.headers.title=Title ui.admin.pagemodels.table.columns.headers.desc=Description ui.admin.pagemodels.table.columns.headers.remove=Delete -\ \tui.admin.pagemodels.table.columns.remove.label=Delete +\ ui.admin.pagemodels.table.columns.remove.label=Delete ui.admin.pagemodels.details.model_name=Name ui.admin.pagemodels.details.model_title=Titel ui.admin.pagemodels.details.model_application=Application @@ -677,3 +677,11 @@ ui.admin.pagemodels.details.edit_properties=Edit properties ui.admin.pagemodels.components.key.label=ID ui.admin.pagemodels.components.key.error.not_empty=The ID of a component can't be empty. ui.admin.pagemodels.table.columns.remove.label=Delete +ui.admin.pagemodels.details.publish=(Re-)Publish +ui.admin.users.table.filter.groupname.placeholder=Name of Group +ui.admin.users.table.filter.groupname.description=Filter groups by name +ui.admin.roles.table.description=Roles +ui.admin.users.table.filter.rolename.placeholder=Name of role +ui.admin.users.table.filter.rolename.description=Filter roles by name +ui.admin.pagemodels.table.columns.headers.islive=Is live? +ui.admin.pagemodels.select_application=Please select an application diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_fr.properties b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_fr.properties index 48b4a49d8..3388b7023 100755 --- a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_fr.properties +++ b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_fr.properties @@ -659,7 +659,7 @@ ui.admin.pagemodels.table.columns.headers.name=Name ui.admin.pagemodels.table.columns.headers.title=Title ui.admin.pagemodels.table.columns.headers.desc=Description ui.admin.pagemodels.table.columns.headers.remove=Delete -\ \tui.admin.pagemodels.table.columns.remove.label=Delete +\ ui.admin.pagemodels.table.columns.remove.label=Delete ui.admin.pagemodels.details.model_name=Name ui.admin.pagemodels.details.model_title=Titel ui.admin.pagemodels.details.model_application=Application @@ -668,3 +668,11 @@ ui.admin.pagemodels.details.edit_properties=Edit properties ui.admin.pagemodels.components.key.label=ID ui.admin.pagemodels.components.key.error.not_empty=The ID of a component can't be empty. ui.admin.pagemodels.table.columns.remove.label=Delete +ui.admin.pagemodels.details.publish=(Re-)Publish +ui.admin.users.table.filter.groupname.placeholder=Name of Group +ui.admin.users.table.filter.groupname.description=Filter groups by name +ui.admin.roles.table.description=Roles +ui.admin.users.table.filter.rolename.placeholder=Name of role +ui.admin.users.table.filter.rolename.description=Filter roles by name +ui.admin.pagemodels.table.columns.headers.islive=Is live? +ui.admin.pagemodels.select_application=Please select an application