From e3f2bb67ca82cd2163887fe04d8c47e0c947aee5 Mon Sep 17 00:00:00 2001 From: jensp Date: Fri, 26 Jan 2018 10:31:10 +0000 Subject: [PATCH] CCM NG: DocumentTypes Tab in the Content Section Admin now works. git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@5220 8810af33-2d31-482b-a856-94f89814c4df --- .../cms/ui/type/ContentTypeAdminPane.java | 26 ++-- .../type/ContentTypeAdminPaneController.java | 32 +++-- .../com/arsdigita/cms/ui/type/EditType.java | 115 +++++++++--------- .../contentsection/ContentTypeRepository.java | 46 ++++++- .../core/AbstractEntityRepository.java | 10 +- .../libreccm/core/CcmObjectRepository.java | 6 +- 6 files changed, 149 insertions(+), 86 deletions(-) diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/type/ContentTypeAdminPane.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/type/ContentTypeAdminPane.java index c4ea56cfd..58ec05906 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/type/ContentTypeAdminPane.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/type/ContentTypeAdminPane.java @@ -29,6 +29,8 @@ import com.arsdigita.bebop.event.ActionEvent; import com.arsdigita.bebop.event.ActionListener; import com.arsdigita.bebop.event.FormProcessListener; import com.arsdigita.bebop.event.FormSubmissionListener; +import com.arsdigita.bebop.event.PrintEvent; +import com.arsdigita.bebop.event.PrintListener; import com.arsdigita.cms.CMS; import org.librecms.contentsection.ContentSection; @@ -48,12 +50,14 @@ import com.arsdigita.toolbox.ui.Section; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.core.UnexpectedErrorException; import org.librecms.CmsConstants; import org.librecms.contentsection.ContentSectionManager; import org.librecms.contentsection.ContentTypeManager; import org.librecms.contenttypes.ContentTypeInfo; import java.util.List; +import java.util.TooManyListenersException; /** * This class contains the split pane for the ContentType administration @@ -315,16 +319,16 @@ public final class ContentTypeAdminPane extends BaseAdminPane { implements ActionListener, FormProcessListener { private final Label noTypesAvailableLabel - = new Label(gz("cms.ui.type.select.none")); + = new Label(gz("cms.ui.type.select.none")); private final SelectType selectType; - + public AddTypeContainer() { super(1); - + final Section selectSection = new Section(); selectSection.setHeading(new Label(gz("cms.ui.type.select"))); add(selectSection); - + final GridPanel container = new GridPanel(1); container.add(noTypesAvailableLabel); selectType = new SelectType(); @@ -333,26 +337,26 @@ public final class ContentTypeAdminPane extends BaseAdminPane { container.add(selectType); selectSection.setBody(container); } - + @Override public void actionPerformed(final ActionEvent event) { - + final PageState state = event.getPageState(); final ContentSection section = CMS.getContext().getContentSection(); final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); final ContentTypeAdminPaneController controller = cdiUtil - .findBean(ContentTypeAdminPaneController.class); + .findBean(ContentTypeAdminPaneController.class); final List contentTypes = controller - .getNotAssociatedContentTypes(section); + .getNotAssociatedContentTypes(section); final boolean hasAvailableTypes = !contentTypes.isEmpty(); selectType.setVisible(state, hasAvailableTypes); noTypesAvailableLabel.setVisible(state, !hasAvailableTypes); } - + @Override - public void process(final FormSectionEvent event) + public void process(final FormSectionEvent event) throws FormProcessException { - + final PageState state = event.getPageState(); resetPane(state); } diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/type/ContentTypeAdminPaneController.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/type/ContentTypeAdminPaneController.java index 432d79b44..63c424f20 100644 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/type/ContentTypeAdminPaneController.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/type/ContentTypeAdminPaneController.java @@ -31,12 +31,19 @@ import java.nio.charset.IllegalCharsetNameException; import java.util.ArrayList; import java.util.List; import java.util.Locale; +import java.util.Objects; import java.util.Optional; import java.util.ResourceBundle; import java.util.stream.Collectors; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; +import javax.persistence.EntityManager; +import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.JoinType; +import javax.persistence.criteria.Root; import javax.transaction.Transactional; /** @@ -50,17 +57,20 @@ import javax.transaction.Transactional; @RequestScoped class ContentTypeAdminPaneController { + @Inject + private EntityManager entityManager; + + @Inject + private ContentSectionRepository sectionRepo; + @Inject private ContentTypeRepository typeRepo; @Inject private ContentTypesManager typesManager; - @Inject - private ContentSectionRepository sectionRepo; - @Transactional(Transactional.TxType.REQUIRED) - public List getTypeList(final ContentSection section) { + protected List getTypeList(final ContentSection section) { final List types = typeRepo.findByContentSection(section); return types.stream() @@ -85,7 +95,7 @@ class ContentTypeAdminPaneController { } @Transactional(Transactional.TxType.REQUIRED) - public List getNotAssociatedContentTypes( + protected List getNotAssociatedContentTypes( final ContentSection section) { final List availableTypes = typesManager @@ -103,7 +113,7 @@ class ContentTypeAdminPaneController { } @Transactional(Transactional.TxType.REQUIRED) - public LifecycleDefinition getLifecycleDefinition(final ContentType type) { + protected LifecycleDefinition getLifecycleDefinition(final ContentType type) { final ContentType contentType = typeRepo .findById(type.getObjectId()) @@ -116,7 +126,7 @@ class ContentTypeAdminPaneController { } @Transactional(Transactional.TxType.REQUIRED) - public Optional getLifecycleDefinitionLabel(final ContentType type, + protected Optional getLifecycleDefinitionLabel(final ContentType type, final Locale locale) { final LifecycleDefinition lifecycleDefinition = getLifecycleDefinition( @@ -130,7 +140,7 @@ class ContentTypeAdminPaneController { } @Transactional(Transactional.TxType.REQUIRED) - public Workflow getWorkflowTemplate(final ContentType type) { + protected Workflow getWorkflowTemplate(final ContentType type) { final ContentType contentType = typeRepo .findById(type.getObjectId()) @@ -143,7 +153,7 @@ class ContentTypeAdminPaneController { } @Transactional(Transactional.TxType.REQUIRED) - public Optional getWorkflowTemplateName(final ContentType type, + protected Optional getWorkflowTemplateName(final ContentType type, final Locale locale) { final Workflow workflowTemplate = getWorkflowTemplate(type); @@ -156,7 +166,7 @@ class ContentTypeAdminPaneController { } @Transactional(Transactional.TxType.REQUIRED) - public List getLifecycleDefinitions( + protected List getLifecycleDefinitions( final ContentSection section) { final ContentSection contentSection = sectionRepo @@ -170,7 +180,7 @@ class ContentTypeAdminPaneController { } @Transactional(Transactional.TxType.REQUIRED) - public List getWorkflowTemplates( + protected List getWorkflowTemplates( final ContentSection section) { final ContentSection contentSection = sectionRepo diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/type/EditType.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/type/EditType.java index 6a7249b82..d3c251f48 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/type/EditType.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/type/EditType.java @@ -75,29 +75,29 @@ public class EditType extends CMSForm private static final Logger LOGGER = LogManager.getLogger(EditType.class); - private final SingleSelectionModel m_types; + private final SingleSelectionModel selectedTypeModel; // Form widgets - private Hidden m_id; + private final Hidden idField; // private TextField m_label; // private TextArea m_description; - private SingleSelect m_lcSelect; - private SingleSelect m_wfSelect; - private Submit m_submit; - private Submit m_cancel; + private final SingleSelect lifecycleSelect; + private final SingleSelect workflowSelect; + private final Submit submitButton; + private final Submit cancelButton; /** - * @param model The content type selection model. This tells the form which - * content type is selected. + * @param selectedTypeModel The content type selection model. This tells the + * form which content type is selected. */ - public EditType(final SingleSelectionModel model) { + public EditType(final SingleSelectionModel selectedTypeModel) { super("EditContentType"); - m_types = model; + this.selectedTypeModel = selectedTypeModel; - m_id = new Hidden(new LongParameter("id")); - m_id.addValidationListener(new NotNullValidationListener()); - add(m_id); + idField = new Hidden(new LongParameter("id")); + idField.addValidationListener(new NotNullValidationListener()); + super.add(idField); // add(new Label(new GlobalizedMessage("cms.ui.type.label", // CmsConstants.CMS_BUNDLE))); @@ -116,40 +116,40 @@ public class EditType extends CMSForm // m_description.setRows(5); // m_description.setWrap(TextArea.SOFT); // add(m_description); - add(new Label(new GlobalizedMessage("cms.ui.type.lifecycle", - CmsConstants.CMS_BUNDLE))); - m_lcSelect = new SingleSelect(new LongParameter("lifecycle")); + super.add(new Label(new GlobalizedMessage("cms.ui.type.lifecycle", + CmsConstants.CMS_BUNDLE))); + lifecycleSelect = new SingleSelect(new LongParameter("lifecycle")); try { - m_lcSelect.addPrintListener(new SelectLifecyclePrintListener()); + lifecycleSelect.addPrintListener(new SelectLifecyclePrintListener()); } catch (TooManyListenersException e) { throw new UncheckedWrapperException("TooManyListeners: " + e .getMessage(), e); } - add(m_lcSelect); + super.add(lifecycleSelect); - add(new Label(new GlobalizedMessage("cms.ui.type.workflow", - CmsConstants.CMS_BUNDLE))); - m_wfSelect = new SingleSelect(new LongParameter("workflow")); + super.add(new Label(new GlobalizedMessage("cms.ui.type.workflow", + CmsConstants.CMS_BUNDLE))); + workflowSelect = new SingleSelect(new LongParameter("workflow")); try { - m_wfSelect.addPrintListener(new SelectWorkflowPrintListener()); - } catch (TooManyListenersException e) { - throw new UncheckedWrapperException("TooManyListeners: " + e - .getMessage(), e); + workflowSelect.addPrintListener(new SelectWorkflowPrintListener()); + } catch (TooManyListenersException ex) { + throw new UncheckedWrapperException("TooManyListeners: " + ex + .getMessage(), ex); } - add(m_wfSelect); + super.add(workflowSelect); - SimpleContainer s = new SimpleContainer(); - m_submit = new Submit("submit"); - m_submit.setButtonLabel("Save"); - s.add(m_submit); - m_cancel = new Submit("cancel"); - m_cancel.setButtonLabel("Cancel"); - s.add(m_cancel); - add(s, ColumnPanel.FULL_WIDTH | ColumnPanel.CENTER); + final SimpleContainer buttonContainer = new SimpleContainer(); + submitButton = new Submit(new GlobalizedMessage("cms.ui.save", + CmsConstants.CMS_BUNDLE)); + buttonContainer.add(submitButton); + cancelButton = new Submit(new GlobalizedMessage("cms.ui.cancel", + CmsConstants.CMS_BUNDLE)); + buttonContainer.add(cancelButton); + super.add(buttonContainer, ColumnPanel.FULL_WIDTH | ColumnPanel.CENTER); - addInitListener(this); - addSubmissionListener(new TypeSecurityListener()); - addProcessListener(this); + super.addInitListener(this); + super.addSubmissionListener(new TypeSecurityListener()); + super.addProcessListener(this); } /** @@ -161,7 +161,7 @@ public class EditType extends CMSForm */ @Override public boolean isCancelled(final PageState state) { - return m_cancel.isSelected(state); + return cancelButton.isSelected(state); } /** @@ -170,7 +170,7 @@ public class EditType extends CMSForm * @return the cancel button on the form */ public Submit getCancelButton() { - return m_cancel; + return cancelButton; } /** @@ -180,13 +180,13 @@ public class EditType extends CMSForm */ @Override public void init(final FormSectionEvent event) { + final FormData data = event.getFormData(); final PageState state = event.getPageState(); - final ContentSection section = CMS.getContext().getContentSection(); - - final KernelConfig kernelConfig = KernelConfig.getConfig(); - +// final ContentSection section = CMS.getContext().getContentSection(); +// +// final KernelConfig kernelConfig = KernelConfig.getConfig(); final ContentType type = getContentType(state); final long typeId = type.getObjectId(); // final String label = type.getLabel().getValue(kernelConfig @@ -194,18 +194,18 @@ public class EditType extends CMSForm // final String description = type.getDescription().getValue(kernelConfig // .getDefaultLocale()); - data.put(m_id.getName(), typeId); + data.put(idField.getName(), typeId); // data.put(m_label.getName(), label); // data.put(m_description.getName(), description); final LifecycleDefinition cycle = type.getDefaultLifecycle(); if (cycle != null) { - data.put(m_lcSelect.getName(), cycle.getDefinitionId()); + data.put(lifecycleSelect.getName(), cycle.getDefinitionId()); } - Workflow template = type.getDefaultWorkflow(); + final Workflow template = type.getDefaultWorkflow(); if (template != null) { - data.put(m_wfSelect.getName(), template.getWorkflowId()); + data.put(workflowSelect.getName(), template.getWorkflowId()); } } @@ -214,7 +214,8 @@ public class EditType extends CMSForm * model. */ private ContentType getContentType(final PageState state) { - final String key = m_types.getSelectedKey(state); + + final String key = selectedTypeModel.getSelectedKey(state); final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); final ContentTypeRepository typeRepo = cdiUtil.findBean( @@ -222,7 +223,9 @@ public class EditType extends CMSForm final Optional result; try { - result = typeRepo.findById(Long.parseLong(key)); + result = typeRepo.findByIdAndFetchAttributes(Long.parseLong(key), + "defaultLifecycle", + "defaultWorkflow"); } catch (NumberFormatException ex) { throw new UncheckedWrapperException(String.format( "The provided key \"%s\" is not a long.", key), @@ -253,11 +256,11 @@ public class EditType extends CMSForm final ContentSection section = CMS.getContext().getContentSection(); // Read form variables. - final Long key = (Long) data.get(m_id.getName()); + final Long key = (Long) data.get(idField.getName()); // final String label = (String) data.get(m_label.getName()); // final String description = (String) data.get(m_description.getName()); - final Long lifecycleId = (Long) data.get(m_lcSelect.getName()); - final Long workflowId = (Long) data.get(m_wfSelect.getName()); + final Long lifecycleId = (Long) data.get(lifecycleSelect.getName()); + final Long workflowId = (Long) data.get(workflowSelect.getName()); final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); final ContentTypeRepository typeRepo = cdiUtil.findBean( @@ -293,11 +296,10 @@ public class EditType extends CMSForm } final Workflow defaultWorkflow; if (workflowId == 0) { - defaultWorkflow = null; + defaultWorkflow = null; } else { defaultWorkflow = workflowRepo.findById(workflowId).get(); } - typeManager.setDefaultLifecycle(type.get(), defaultLifecycle); typeManager.setDefaultWorkflow(type.get(), defaultWorkflow); @@ -372,8 +374,9 @@ public class EditType extends CMSForm .getDefaultLocale(); templates.forEach(template -> { workflowSelect.addOption( - new Option(Long.toString(template.getWorkflowId()), - template.getName().getValue(defaultLocale))); + new Option( + Long.toString(template.getWorkflowId()), + new Text(template.getName().getValue(defaultLocale)))); }); } diff --git a/ccm-cms/src/main/java/org/librecms/contentsection/ContentTypeRepository.java b/ccm-cms/src/main/java/org/librecms/contentsection/ContentTypeRepository.java index afff87e26..f6f95e1df 100644 --- a/ccm-cms/src/main/java/org/librecms/contentsection/ContentTypeRepository.java +++ b/ccm-cms/src/main/java/org/librecms/contentsection/ContentTypeRepository.java @@ -27,7 +27,14 @@ import java.util.List; import java.util.Optional; import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.persistence.EntityManager; +import javax.persistence.NoResultException; import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.JoinType; +import javax.persistence.criteria.Root; import javax.transaction.Transactional; /** @@ -38,6 +45,11 @@ import javax.transaction.Transactional; public class ContentTypeRepository extends AbstractEntityRepository { + private static final long serialVersionUID = 5871606965722748001L; + + @Inject + private EntityManager entityManager; + @Override public Class getEntityClass() { return ContentType.class; @@ -48,6 +60,30 @@ public class ContentTypeRepository return type.getObjectId() == 0; } + public Optional findByIdAndFetchAttributes( + final Long typeId, final String... fetchAttributes) { + + final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + final CriteriaQuery criteriaQuery = builder + .createQuery(getEntityClass()); + + final Root from = criteriaQuery.from(getEntityClass()); + for (final String fetchAttribute : fetchAttributes) { + from.fetch(fetchAttribute, JoinType.LEFT); + } + + criteriaQuery.select(from); + criteriaQuery.where(builder.equal(from.get("objectId"), typeId)); + + try { + final TypedQuery query = entityManager + .createQuery(criteriaQuery); + return Optional.of(query.getSingleResult()); + } catch (NoResultException ex) { + return Optional.empty(); + } + } + /** * Finds all {@link ContentType}s of a specific content section. * @@ -188,8 +224,8 @@ public class ContentTypeRepository public void delete( @RequiresPrivilege(AdminPrivileges.ADMINISTER_CONTENT_TYPES) final ContentType type) { - - if (isContentTypeInUse(type)) { + + if (isContentTypeInUse(type)) { throw new IllegalArgumentException(String.format( "Contenttype \"%s\" in section \"%s\" is in use and can't be" + "deleted.", @@ -199,7 +235,7 @@ public class ContentTypeRepository super.delete(type); } } - + /** * Checks if there is any item of the provided content type and the content * section to which the type belongs. @@ -212,9 +248,9 @@ public class ContentTypeRepository final TypedQuery query = getEntityManager().createNamedQuery( "ContentType.isInUse", Long.class); query.setParameter("type", type); - + final long result = query.getSingleResult(); - + return result > 0; } diff --git a/ccm-core/src/main/java/org/libreccm/core/AbstractEntityRepository.java b/ccm-core/src/main/java/org/libreccm/core/AbstractEntityRepository.java index 1af0b12ee..bdee13ee7 100644 --- a/ccm-core/src/main/java/org/libreccm/core/AbstractEntityRepository.java +++ b/ccm-core/src/main/java/org/libreccm/core/AbstractEntityRepository.java @@ -18,7 +18,6 @@ */ package org.libreccm.core; - import java.io.Serializable; import java.util.HashMap; import java.util.List; @@ -32,6 +31,7 @@ import javax.persistence.EntityManager; import javax.persistence.TypedQuery; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.JoinType; import javax.persistence.criteria.Root; import javax.transaction.Transactional; @@ -137,6 +137,8 @@ public abstract class AbstractEntityRepository implements Serializable { @Transactional(Transactional.TxType.REQUIRED) public Optional findById(final K entityId) { + Objects.requireNonNull(entityId); + return Optional.ofNullable(entityManager.find(getEntityClass(), entityId)); } @@ -144,6 +146,9 @@ public abstract class AbstractEntityRepository implements Serializable { @Transactional(Transactional.TxType.REQUIRED) public Optional findById(final K entityId, final String entityGraphName) { + Objects.requireNonNull(entityId); + Objects.requireNonNull(entityGraphName); + @SuppressWarnings("unchecked") final EntityGraph entityGraph = (EntityGraph) entityManager. getEntityGraph(entityGraphName); @@ -154,6 +159,9 @@ public abstract class AbstractEntityRepository implements Serializable { public Optional findById(final K entityId, final EntityGraph entityGraph) { + Objects.requireNonNull(entityId); + Objects.requireNonNull(entityGraph); + final Map hints = new HashMap<>(); hints.put(FETCH_GRAPH_HINT_KEY, entityGraph); return Optional.ofNullable(entityManager.find(getEntityClass(), diff --git a/ccm-core/src/main/java/org/libreccm/core/CcmObjectRepository.java b/ccm-core/src/main/java/org/libreccm/core/CcmObjectRepository.java index 45934f826..d0548374b 100644 --- a/ccm-core/src/main/java/org/libreccm/core/CcmObjectRepository.java +++ b/ccm-core/src/main/java/org/libreccm/core/CcmObjectRepository.java @@ -22,11 +22,13 @@ import javax.enterprise.context.RequestScoped; import javax.persistence.NoResultException; import javax.persistence.TypedQuery; import javax.transaction.Transactional; + import java.util.Optional; import java.util.UUID; import static org.libreccm.core.CoreConstants.ACCESS_DENIED; + /** * A repository class for {@link CcmObject} entities. * @@ -43,7 +45,7 @@ import static org.libreccm.core.CoreConstants.ACCESS_DENIED; public class CcmObjectRepository extends AbstractEntityRepository { private static final long serialVersionUID = 5033157795875521195L; - + @Override public Class getEntityClass() { return CcmObject.class; @@ -86,7 +88,7 @@ public class CcmObjectRepository extends AbstractEntityRepository