From be142631773f949113902e2286ee15e47a5dcb53 Mon Sep 17 00:00:00 2001 From: jensp Date: Fri, 19 May 2017 18:11:24 +0000 Subject: [PATCH] CCM NG/ccm-cms: ArticlePropertiesStep: Added parameter for selected language (for finished yet) git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4744 8810af33-2d31-482b-a856-94f89814c4df --- .../ui/ArticlePropertiesStep.java | 11 +- .../contenttypes/ui/ArticlePropertyForm.java | 1 - .../ui/GenericArticlePropertiesStep.java | 18 +- .../ui/GenericArticlePropertyForm.java | 2 - .../cms/ui/authoring/AuthoringKitWizard.java | 121 ++++++++----- .../cms/ui/authoring/SimpleEditStep.java | 10 +- .../toolbox/ui/DomainObjectPropertySheet.java | 42 ++++- .../java/org/libreccm/admin/ui/AdminView.java | 5 + .../ui/usersgroupsroles/GroupsTable.java | 4 +- .../admin/ui/usersgroupsroles/RolesTable.java | 163 ++++++++++++++++++ .../RolesTableDataProvider.java | 103 +++++++++++ .../ui/usersgroupsroles/UsersGroupsRoles.java | 23 ++- .../UsersTableDataProvider.java | 1 - .../ui/admin/AdminResources.properties | 2 + .../ui/admin/AdminResources_de.properties | 2 + .../ui/admin/AdminResources_en.properties | 2 + .../ui/admin/AdminResources_fr.properties | 2 + 17 files changed, 444 insertions(+), 68 deletions(-) create mode 100644 ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RolesTable.java create mode 100644 ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RolesTableDataProvider.java diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/contenttypes/ui/ArticlePropertiesStep.java b/ccm-cms/src/main/java/com/arsdigita/cms/contenttypes/ui/ArticlePropertiesStep.java index 98494a87c..88e470e1b 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/contenttypes/ui/ArticlePropertiesStep.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/contenttypes/ui/ArticlePropertiesStep.java @@ -19,9 +19,9 @@ package com.arsdigita.cms.contenttypes.ui; import com.arsdigita.bebop.Component; +import com.arsdigita.bebop.parameters.StringParameter; import com.arsdigita.cms.ItemSelectionModel; -import org.librecms.contenttypes.Article; import com.arsdigita.cms.ui.authoring.AuthoringKitWizard; import com.arsdigita.cms.ui.authoring.BasicPageForm; @@ -43,10 +43,13 @@ public class ArticlePropertiesStep extends GenericArticlePropertiesStep { * The name of the editing sheet added to this step */ public final static String EDIT_SHEET_NAME = "edit"; + + private StringParameter selectedLanuageParam; - public ArticlePropertiesStep(ItemSelectionModel itemModel, - AuthoringKitWizard parent) { - super(itemModel, parent); + public ArticlePropertiesStep(final ItemSelectionModel itemModel, + final AuthoringKitWizard parent, + final StringParameter selectedLanguageParam) { + super(itemModel, parent, selectedLanguageParam); } @Override diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/contenttypes/ui/ArticlePropertyForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/contenttypes/ui/ArticlePropertyForm.java index c9853b985..98137dbc5 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/contenttypes/ui/ArticlePropertyForm.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/contenttypes/ui/ArticlePropertyForm.java @@ -30,7 +30,6 @@ import com.arsdigita.bebop.parameters.ParameterModel; import com.arsdigita.bebop.parameters.StringInRangeValidationListener; import com.arsdigita.bebop.parameters.StringParameter; -import org.librecms.contentsection.ContentSection; import com.arsdigita.cms.ItemSelectionModel; import com.arsdigita.globalization.GlobalizedMessage; diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/contenttypes/ui/GenericArticlePropertiesStep.java b/ccm-cms/src/main/java/com/arsdigita/cms/contenttypes/ui/GenericArticlePropertiesStep.java index 5cd61cc6c..14567ff1b 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/contenttypes/ui/GenericArticlePropertiesStep.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/contenttypes/ui/GenericArticlePropertiesStep.java @@ -20,8 +20,9 @@ package com.arsdigita.cms.contenttypes.ui; import com.arsdigita.bebop.Component; import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.PropertyEditor; -import org.librecms.contentsection.ContentSection; +import com.arsdigita.bebop.parameters.StringParameter; import com.arsdigita.cms.ItemSelectionModel; import com.arsdigita.toolbox.ui.DomainObjectPropertySheet; @@ -51,11 +52,16 @@ public class GenericArticlePropertiesStep extends SimpleEditStep { public static final String EDIT_SHEET_NAME = "edit"; private DomainObjectPropertySheet domainObjectPropertySheet; + + private StringParameter selectedLanguageParam; - public GenericArticlePropertiesStep(final ItemSelectionModel itemModel, - final AuthoringKitWizard parent) { + public GenericArticlePropertiesStep( + final ItemSelectionModel itemModel, + final AuthoringKitWizard parent, + final StringParameter selectedLanguageParam) { - super(itemModel, parent); + super(itemModel, parent, selectedLanguageParam); + this.selectedLanguageParam = selectedLanguageParam; setDefaultEditKey(EDIT_SHEET_NAME); createEditSheet(itemModel); @@ -76,6 +82,10 @@ public class GenericArticlePropertiesStep extends SimpleEditStep { setDisplayComponent(getGenericArticlePropertySheet(itemModel)); } + protected StringParameter getSelectedLanguageParam() { + return selectedLanguageParam; + } + /** * Returns a component that displays the properties of the Article specified * by the ItemSelectionModel passed in. diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/contenttypes/ui/GenericArticlePropertyForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/contenttypes/ui/GenericArticlePropertyForm.java index 5a7f997bf..4fd8498d4 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/contenttypes/ui/GenericArticlePropertyForm.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/contenttypes/ui/GenericArticlePropertyForm.java @@ -30,11 +30,9 @@ import org.librecms.contenttypes.Article; import com.arsdigita.cms.ui.authoring.BasicPageForm; -import org.apache.logging.log4j.LogManager; import org.libreccm.cdi.utils.CdiUtil; import org.librecms.contentsection.ContentItemRepository; -import javax.enterprise.inject.spi.CDI; /** * Form to edit the basic properties of an article. This form can be extended to diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/AuthoringKitWizard.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/AuthoringKitWizard.java index 7379c930c..a23631771 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/AuthoringKitWizard.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/AuthoringKitWizard.java @@ -36,6 +36,7 @@ import com.arsdigita.bebop.event.FormProcessListener; import com.arsdigita.bebop.event.FormSectionEvent; import com.arsdigita.bebop.Label; import com.arsdigita.bebop.list.ListCellRenderer; +import com.arsdigita.bebop.parameters.StringParameter; import org.librecms.contentsection.ContentType; @@ -69,6 +70,7 @@ import org.apache.logging.log4j.LogManager; import org.arsdigita.cms.CMSConfig; import org.libreccm.cdi.utils.CdiUtil; import org.libreccm.configuration.ConfigurationManager; +import org.libreccm.l10n.GlobalizationHelper; import org.librecms.CmsConstants; import org.librecms.contentsection.ContentItem; import org.librecms.contenttypes.AuthoringKit; @@ -99,18 +101,23 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { /** * Private Logger instance for this class */ - private static final Logger LOGGER = LogManager.getLogger( - AuthoringKitWizard.class); + private static final Logger LOGGER = LogManager + .getLogger(AuthoringKitWizard.class); + + public final String SELECTED_LANGUAGE = "selectedLanguage"; + private static Class[] arguments = new Class[]{ ItemSelectionModel.class, - AuthoringKitWizard.class + AuthoringKitWizard.class, + StringParameter.class }; private static Class[] userDefinedArgs = new Class[]{ ItemSelectionModel.class, AuthoringKitWizard.class, ContentType.class }; - private static final java.util.List ASSETS = new ArrayList(); + private static final java.util.List ASSETS + = new ArrayList(); private final Object[] values; private final ContentTypeInfo typeInfo; private final AuthoringKitInfo kitInfo; @@ -125,6 +132,8 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { private final SimpleContainer stepsContainer; private final TaskFinishForm m_taskFinishForm; + private final StringParameter selectedLanguageParam; + /** * The name of the state parameter that determines whether the wizard is in * item creation mode or item editing mode. @@ -135,15 +144,17 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { */ public static final String CREATION = "_creation_"; - private final static String SEC_PAGE_EDIT_DYN = "com.arsdigita.cms.ui.authoring.SecondaryPageEditDynamic"; - private final static String PAGE_EDIT_DYN = "com.arsdigita.cms.ui.authoring.PageEditDynamic"; + private final static String SEC_PAGE_EDIT_DYN + = "com.arsdigita.cms.ui.authoring.SecondaryPageEditDynamic"; + private final static String PAGE_EDIT_DYN + = "com.arsdigita.cms.ui.authoring.PageEditDynamic"; /** * Construct a new AuthoringKitWizard. Add all the steps in the authoring * kit to the wizard. * - * @param typeInfo The content type of the items that this wizard will - * handle + * @param typeInfo The content type of the items that this wizard will + * handle * @param selectionModel */ public AuthoringKitWizard(final ContentTypeInfo typeInfo, @@ -153,12 +164,19 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); final ConfigurationManager confManager = cdiUtil.findBean( - ConfigurationManager.class); + ConfigurationManager.class); + + selectedLanguageParam = new StringParameter(SELECTED_LANGUAGE); + final GlobalizationHelper globalizationHelper = cdiUtil + .findBean(GlobalizationHelper.class); + selectedLanguageParam.setDefaultValue(globalizationHelper + .getNegotiatedLocale() + .toString()); this.typeInfo = typeInfo; kitInfo = typeInfo.getAuthoringKit(); this.selectionModel = selectionModel; - values = new Object[]{selectionModel, this}; + values = new Object[]{selectionModel, this, selectedLanguageParam}; workflowRequestLocal = new ItemWorkflowRequestLocal(); labels = new SequentialMap(); @@ -198,6 +216,7 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { } return new ControlLink(label); } + }); bodyPanel = new ModalPanel(); @@ -208,17 +227,17 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { bodyPanel.setDefault(stepsContainer); final java.util.List steps = kitInfo. - getAuthoringSteps(); + getAuthoringSteps(); if (Assert.isEnabled()) { Assert.isTrue(!steps.isEmpty(), String.format("The authoring kit for content type " - + "s\"%s\" has no steps.", + + "s\"%s\" has no steps.", typeInfo.getContentItemClass().getName())); } final CMSConfig cmsConfig = confManager.findConfiguration( - CMSConfig.class); + CMSConfig.class); StepComponent panel = null; for (final AuthoringStepInfo step : steps) { @@ -233,16 +252,16 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { * compatibility */ final ResourceBundle labelBundle = ResourceBundle.getBundle(step. - getLabelBundle()); + getLabelBundle()); final ResourceBundle descBundle = ResourceBundle.getBundle(step. - getDescriptionBundle()); + getDescriptionBundle()); final String labelKey = step.getLabelKey(); final String label = labelBundle.getString(labelKey); final String descriptionKey = step.getDescriptionKey(); final String description = descBundle.getString(descriptionKey); final Class componentClass = step. - getComponent(); + getComponent(); final String compClassName = componentClass.getName(); if (panel != null) { @@ -253,7 +272,7 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { final Component comp; if (compClassName.equals(SEC_PAGE_EDIT_DYN) - || compClassName.equals(PAGE_EDIT_DYN)) { + || compClassName.equals(PAGE_EDIT_DYN)) { comp = instantiateUserDefinedStep(compClassName, typeInfo); } else { comp = instantiateStep(compClassName); @@ -262,7 +281,7 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { // XXX should be optional if (comp instanceof AuthoringStepComponent) { ((AuthoringStepComponent) comp).addCompletionListener( - new StepCompletionListener()); + new StepCompletionListener()); } final GlobalizedMessage gzLabel; @@ -283,8 +302,8 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { } } - final Class typeClass = typeInfo. - getContentItemClass(); + final Class typeClass = typeInfo + .getContentItemClass(); final java.util.List skipSteps = cmsConfig.getSkipAssetSteps(); if (LOGGER.isDebugEnabled()) { @@ -320,7 +339,7 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { Component comp = instantiateStep(step.getName()); if (comp instanceof AuthoringStepComponent) { ((AuthoringStepComponent) comp).addCompletionListener( - new StepCompletionListener()); + new StepCompletionListener()); } panel.add(comp); @@ -340,11 +359,12 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { @Override public final void process(final FormSectionEvent event) - throws FormProcessException { + throws FormProcessException { final PageState state = event.getPageState(); assignedTaskTable.getRowSelectionModel().clearSelection(state); } + }); } @@ -367,6 +387,7 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { } } } + } /** @@ -388,12 +409,13 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { Object nextStep = step.getNextStepKey(); if (nextStep != null) { list.getSelectionModel().setSelectedKey( - state, nextStep.toString()); + state, nextStep.toString()); } } } } } + } @Override @@ -416,13 +438,14 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { if (state.isVisibleOnPage(AuthoringKitWizard.this)) { final SingleSelectionModel model = list. - getSelectionModel(); + getSelectionModel(); if (!model.isSelected(state)) { model.setSelectedKey(state, defaultKey); } } } + }); } @@ -438,7 +461,7 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { // image step application was loaded. Solution is to ensure initialiser in new project // runs after original ccm-ldn-image-step initializer and override the registered step here LOGGER.debug("registering asset step - label: \"{}\"; " - + "step class: \"%s\"", + + "step class: \"%s\"", label.localize(), step.getName()); @@ -456,16 +479,16 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { * */ if ((thisObjectType.equals(baseObjectType)) - && (thisLabel.localize().equals(label.localize()))) { + && (thisLabel.localize().equals(label.localize()))) { LOGGER.debug( - "registering authoring step with same label as previously registered step"); + "registering authoring step with same label as previously registered step"); ASSETS.remove(data); break; } } ASSETS.add( - new AssetStepEntry(baseObjectType, step, label, description, - sortKey)); + new AssetStepEntry(baseObjectType, step, label, description, + sortKey)); Collections.sort(ASSETS); } @@ -541,6 +564,7 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { return sortKey.compareTo(other.getSortKey()); } } + } /** @@ -573,6 +597,7 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { * RuntimeException on failure. * * @param className The Java class name of the step + * * @return The instance of the component. */ protected Component instantiateStep(final String className) { @@ -589,15 +614,15 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { return component; } catch (ClassNotFoundException - | IllegalAccessException - | IllegalArgumentException - | InstantiationException - | InvocationTargetException - | NoSuchMethodException - | SecurityException ex) { + | IllegalAccessException + | IllegalArgumentException + | InstantiationException + | InvocationTargetException + | NoSuchMethodException + | SecurityException ex) { throw new UncheckedWrapperException(String.format( - "Failed to instantiate authoring kit component \"{}\".", - className), + "Failed to instantiate authoring kit component \"{}\".", + className), ex); } } @@ -606,29 +631,30 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { * Instantiate the specified authoring kit step for a user defined content * type. Will throw a RuntimeException on failure. * - * @param className The Java class name of the step + * @param className The Java class name of the step * @param originatingType + * * @return */ protected Component instantiateUserDefinedStep( - final String className, final ContentTypeInfo originatingType) { + final String className, final ContentTypeInfo originatingType) { Object[] vals; try { // Get the creation component final Class createClass = Class.forName(className); final Constructor constr = createClass.getConstructor( - userDefinedArgs); + userDefinedArgs); final Object[] userDefinedVals = new Object[]{selectionModel, this, originatingType}; final Component component = (Component) constr.newInstance( - userDefinedVals); + userDefinedVals); return component; } catch (ClassNotFoundException | NoSuchMethodException - | InstantiationException | IllegalAccessException - | InvocationTargetException ex) { + | InstantiationException | IllegalAccessException + | InvocationTargetException ex) { throw new UncheckedWrapperException(ex); } } @@ -661,6 +687,7 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { public void setNextStepKey(final Object nextKey) { this.nextKey = nextKey; } + } private final class TaskSelectionRequestLocal extends TaskRequestLocal { @@ -668,12 +695,13 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { @Override protected final Object initialValue(final PageState state) { final String key = assignedTaskTable - .getRowSelectionModel() - .getSelectedKey(state) - .toString(); + .getRowSelectionModel() + .getSelectedKey(state) + .toString(); return CmsTaskType.valueOf(key); } + } protected final static GlobalizedMessage gz(final String key) { @@ -683,4 +711,5 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { protected final static String lz(final String key) { return (String) gz(key).localize(); } + } diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/SimpleEditStep.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/SimpleEditStep.java index f92223541..351210b96 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/SimpleEditStep.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/SimpleEditStep.java @@ -73,6 +73,8 @@ public class SimpleEditStep extends SecurityPropertyEditor private StringParameter streamlinedCreationParameter; private static final String STREAMLINED = "_streamlined"; private static final String STREAMLINED_DONE = "1"; + + private final StringParameter selectedLanguageParameter; private static List additionalDisplayComponents = new ArrayList<>(); @@ -105,8 +107,9 @@ public class SimpleEditStep extends SecurityPropertyEditor * stepBack, in its process listener. */ public SimpleEditStep(final ItemSelectionModel itemModel, - final AuthoringKitWizard parent) { - this(itemModel, parent, ""); + final AuthoringKitWizard parent, + final StringParameter selectedLanguageParam) { + this(itemModel, parent, selectedLanguageParam, ""); } /** @@ -126,11 +129,14 @@ public class SimpleEditStep extends SecurityPropertyEditor */ public SimpleEditStep(final ItemSelectionModel itemSelectionModel, final AuthoringKitWizard authoringKitWizard, + final StringParameter selectedLanguageParam, final String parameterSuffix) { super(); this.authoringKitWizard = authoringKitWizard; this.itemSelectionModel = itemSelectionModel; + + this.selectedLanguageParameter = selectedLanguageParam; streamlinedCreationParameter = new StringParameter( authoringKitWizard.getContentType().getContentItemClass().getName() diff --git a/ccm-core/src/main/java/com/arsdigita/toolbox/ui/DomainObjectPropertySheet.java b/ccm-core/src/main/java/com/arsdigita/toolbox/ui/DomainObjectPropertySheet.java index f629c8d50..a62fdb746 100755 --- a/ccm-core/src/main/java/com/arsdigita/toolbox/ui/DomainObjectPropertySheet.java +++ b/ccm-core/src/main/java/com/arsdigita/toolbox/ui/DomainObjectPropertySheet.java @@ -22,13 +22,16 @@ import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.PropertySheet; import com.arsdigita.bebop.PropertySheetModel; import com.arsdigita.bebop.PropertySheetModelBuilder; +import com.arsdigita.bebop.parameters.StringParameter; import com.arsdigita.globalization.GlobalizedMessage; +import com.arsdigita.kernel.KernelConfig; import com.arsdigita.toolbox.ToolboxConstants; import com.arsdigita.ui.CcmObjectSelectionModel; import com.arsdigita.util.LockableImpl; import org.libreccm.core.CcmObject; import org.libreccm.core.UnexpectedErrorException; +import org.libreccm.l10n.LocalizedString; import java.beans.BeanInfo; import java.beans.IntrospectionException; @@ -40,6 +43,7 @@ import java.util.Arrays; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Locale; import java.util.Optional; import java.util.StringTokenizer; @@ -87,6 +91,8 @@ public class DomainObjectPropertySheet extends PropertySheet { private AttributeFormatter toStringFormatter; private AttributeFormatter recursiveFormatter; + private StringParameter selectedLanguageParam; + /** * Construct a new DomainObjectPropertySheet * @@ -111,10 +117,19 @@ public class DomainObjectPropertySheet extends PropertySheet { final CcmObjectSelectionModel objectSelectionModel, final boolean valueOutputEscape) { + this(objectSelectionModel, valueOutputEscape, null); + } + + public DomainObjectPropertySheet( + final CcmObjectSelectionModel objectSelectionModel, + final boolean valueOutputEscape, + final StringParameter selectedLanguageParam) { + super(new DomainObjectModelBuilder(), valueOutputEscape); this.objectSelectionModel = objectSelectionModel; properties = new LinkedList<>(); + this.selectedLanguageParam = selectedLanguageParam; toStringFormatter = new SimpleAttributeFormatter(); recursiveFormatter = new RecursiveAttributeFormatter(); @@ -481,7 +496,9 @@ public class DomainObjectPropertySheet extends PropertySheet { return (String) defaultMsg.localize(); } - final Optional value = getPropertyValue(obj, attribute); + final Optional value = getPropertyValue(obj, + attribute, + state); if (value.isPresent()) { return value.get().toString(); @@ -544,7 +561,7 @@ public class DomainObjectPropertySheet extends PropertySheet { while (tokenizer.hasMoreTokens()) { token = tokenizer.nextToken(); // Null check - currentObject = getPropertyValue(currentObject, token); + currentObject = getPropertyValue(currentObject, token, state); if (currentObject == null) { return (String) getDefaultValue().localize(); } @@ -561,7 +578,8 @@ public class DomainObjectPropertySheet extends PropertySheet { } private Optional getPropertyValue(final Object obj, - final String property) { + final String property, + final PageState state) { final BeanInfo beanInfo; try { @@ -583,7 +601,23 @@ public class DomainObjectPropertySheet extends PropertySheet { final Object value; try { - value = readMethod.invoke(obj); + final Object tmp = readMethod.invoke(obj); + if (tmp instanceof LocalizedString) { + final LocalizedString localizedString + = (LocalizedString) tmp; + final Locale selectedLocale = new Locale( + (String) state.getValue(selectedLanguageParam)); + final Locale defaultLocale = KernelConfig + .getConfig() + .getDefaultLocale(); + if (localizedString.hasValue(selectedLocale)) { + value = localizedString.getValue(selectedLocale); + } else { + value = ""; + } + } else { + value = tmp; + } } catch (IllegalAccessException | InvocationTargetException ex) { throw new UnexpectedErrorException(ex); } diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/AdminView.java b/ccm-core/src/main/java/org/libreccm/admin/ui/AdminView.java index 14b0e09fe..167bc0937 100644 --- a/ccm-core/src/main/java/org/libreccm/admin/ui/AdminView.java +++ b/ccm-core/src/main/java/org/libreccm/admin/ui/AdminView.java @@ -35,6 +35,7 @@ import com.vaadin.ui.TabSheet; import com.vaadin.ui.VerticalLayout; import org.apache.shiro.subject.Subject; import org.libreccm.admin.ui.usersgroupsroles.GroupsTableDataProvider; +import org.libreccm.admin.ui.usersgroupsroles.RolesTableDataProvider; import org.libreccm.admin.ui.usersgroupsroles.UsersGroupsRoles; import org.libreccm.admin.ui.usersgroupsroles.UsersTableDataProvider; import org.libreccm.l10n.GlobalizationHelper; @@ -87,6 +88,9 @@ public class AdminView extends CustomComponent implements View { @Inject private GroupsTableDataProvider groupsTableDataProvider; + @Inject + private RolesTableDataProvider rolesTableDataProvider; + private ResourceBundle bundle; @Inject @@ -173,6 +177,7 @@ public class AdminView extends CustomComponent implements View { usersGroupsRoles.setUsersTableDataProvider(usersTableDataProvider); usersGroupsRoles.setGroupsTableDataProvider(groupsTableDataProvider); + usersGroupsRoles.setRolesTableDataProvider(rolesTableDataProvider); tabUsersGroupsRoles.setCaption(bundle .getString("ui.admin.tab.users_groups_roles.title")); diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/GroupsTable.java b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/GroupsTable.java index b219b4ddd..5ffb729f2 100644 --- a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/GroupsTable.java +++ b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/GroupsTable.java @@ -77,8 +77,8 @@ public class GroupsTable extends Grid { final HeaderRow filterRow = appendHeaderRow(); final HeaderCell GroupNameFilterCell = filterRow.getCell(COL_NAME); groupNameFilter = new TextField(); - groupNameFilter.setPlaceholder("User name"); - groupNameFilter.setDescription("Filter Groups by Groupname"); + groupNameFilter.setPlaceholder("Group name"); + groupNameFilter.setDescription("Filter Groups by name"); groupNameFilter.addStyleName(ValoTheme.TEXTFIELD_TINY); groupNameFilter .addValueChangeListener(event -> { diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RolesTable.java b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RolesTable.java new file mode 100644 index 000000000..b2bb3b68f --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RolesTable.java @@ -0,0 +1,163 @@ +/* + * 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.libreccm.admin.ui.usersgroupsroles; + +import com.arsdigita.ui.admin.AdminUiConstants; + +import com.vaadin.icons.VaadinIcons; +import com.vaadin.ui.Button; +import com.vaadin.ui.Grid; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.TextField; +import com.vaadin.ui.UI; +import com.vaadin.ui.components.grid.HeaderCell; +import com.vaadin.ui.components.grid.HeaderRow; +import com.vaadin.ui.renderers.ButtonRenderer; +import com.vaadin.ui.themes.ValoTheme; +import org.libreccm.admin.ui.AdminView; +import org.libreccm.security.Role; + +import java.util.Locale; +import java.util.Optional; +import java.util.ResourceBundle; + +/** + * + * @author Jens Pelzetter + */ +public class RolesTable extends Grid { + + private static final long serialVersionUID = 8298191390811634176L; + + private final static String COL_NAME = "name"; + private final static String COL_DESCRIPTION = "description"; + private final static String COL_EDIT = "edit"; + private final static String COL_DELETE = "delete"; + + private final TextField roleNameFilter; + private final Button clearFiltersButton; + private final Button createRoleButton; + + public RolesTable(final AdminView adminView, + final UsersGroupsRoles usersGroupsRoles) { + + super(); + + final ResourceBundle bundle = ResourceBundle + .getBundle(AdminUiConstants.ADMIN_BUNDLE, + UI.getCurrent().getLocale()); + + addColumn(Role::getName) + .setId(COL_NAME) + .setCaption("Name"); + addColumn(role -> { + if (role.getDescription().hasValue(UI.getCurrent().getLocale())) { + return role.getDescription() + .getValue(UI.getCurrent().getLocale()); + } else { + final Optional locale = role + .getDescription() + .getAvailableLocales() + .stream() + .sorted((locale1, locale2) -> { + return locale1.toString().compareTo(locale2.toString()); + }) + .findFirst(); + if (locale.isPresent()) { + return role.getDescription().getValue(locale.get()); + } else { + return ""; + } + } + + }) + .setId(COL_DESCRIPTION) + .setCaption("Description"); + addColumn(user -> bundle.getString("ui.admin.roles.table.edit"), + new ButtonRenderer<>(event -> { + //ToDo Open GroupEditor window + })) + .setId(COL_EDIT); + addColumn(user -> bundle.getString("ui.admin.roles.table.delete"), + new ButtonRenderer<>(event -> { + //ToDo Display Confirm dialog + })) + .setId(COL_DELETE); + + final HeaderRow filterRow = appendHeaderRow(); + final HeaderCell GroupNameFilterCell = filterRow.getCell(COL_NAME); + roleNameFilter = new TextField(); + roleNameFilter.setPlaceholder("Role name"); + roleNameFilter.setDescription("Filter Roles by name"); + roleNameFilter.addStyleName(ValoTheme.TEXTFIELD_TINY); + roleNameFilter + .addValueChangeListener(event -> { + ((RolesTableDataProvider) getDataProvider()) + .setRoleNameFilter(event.getValue().toLowerCase()); + }); + GroupNameFilterCell.setComponent(roleNameFilter); + + final HeaderRow actionsRow = prependHeaderRow(); + final HeaderCell actionsCell = actionsRow.join(COL_NAME, + COL_DESCRIPTION, + COL_EDIT, + COL_DELETE); + clearFiltersButton = new Button("Clear filters"); + clearFiltersButton.setStyleName(ValoTheme.BUTTON_TINY); + clearFiltersButton.setIcon(VaadinIcons.BACKSPACE); + clearFiltersButton.addClickListener(event -> { + roleNameFilter.setValue(""); + }); + + createRoleButton = new Button("New role"); + createRoleButton.setStyleName(ValoTheme.BUTTON_TINY); + createRoleButton.setIcon(VaadinIcons.PLUS); + createRoleButton.addClickListener(event -> { + //ToDo Open GroupEditor + }); + final HorizontalLayout actionsLayout = new HorizontalLayout( + clearFiltersButton, + createRoleButton); + actionsCell.setComponent(actionsLayout); + } + + public void localize() { + + final ResourceBundle bundle = ResourceBundle + .getBundle(AdminUiConstants.ADMIN_BUNDLE, + UI.getCurrent().getLocale()); + + getColumn(COL_NAME) + .setCaption(bundle.getString("ui.admin.roles.table.name")); + + getColumn(COL_DESCRIPTION) + .setCaption(bundle.getString("ui.admin.roles.table.description")); + + roleNameFilter.setPlaceholder( + bundle + .getString("ui.admin.users.table.filter.rolename.placeholder")); + roleNameFilter.setDescription(bundle + .getString("ui.admin.users.table.filter.rolename.description")); + + clearFiltersButton.setCaption(bundle + .getString("ui.admin.users.table.filter.clear")); + + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RolesTableDataProvider.java b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RolesTableDataProvider.java new file mode 100644 index 000000000..7a01c53d3 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RolesTableDataProvider.java @@ -0,0 +1,103 @@ +/* + * 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.libreccm.admin.ui.usersgroupsroles; + +import com.vaadin.cdi.ViewScoped; +import com.vaadin.data.provider.AbstractDataProvider; +import com.vaadin.data.provider.Query; +import org.libreccm.security.Role; + +import java.util.stream.Stream; + +import javax.inject.Inject; +import javax.persistence.EntityManager; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Root; +import javax.transaction.Transactional; + +/** + * + * @author Jens Pelzetter + */ +@ViewScoped +public class RolesTableDataProvider extends AbstractDataProvider { + + private static final long serialVersionUID = 6305886670608199133L; + + @Inject + private EntityManager entityManager; + + private String roleNameFilter; + + @Override + public boolean isInMemory() { + return false; + } + + @Transactional(Transactional.TxType.REQUIRED) + @Override + public int size(final Query query) { + + final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + CriteriaQuery criteriaQuery = builder.createQuery(Long.class); + final Root from = criteriaQuery.from(Role.class); + + criteriaQuery = criteriaQuery.select(builder.count(from)); + + if (roleNameFilter != null && !roleNameFilter.trim().isEmpty()) { + criteriaQuery + .where(builder.like(builder.lower(from.get("name")), + String.format("%s%%", roleNameFilter))); + } + + return entityManager + .createQuery(criteriaQuery) + .getSingleResult() + .intValue(); + } + + @Transactional(Transactional.TxType.REQUIRED) + @Override + public Stream fetch(final Query query) { + + final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + CriteriaQuery criteriaQuery = builder.createQuery(Role.class); + final Root from = criteriaQuery.from(Role.class); + + if (roleNameFilter != null && !roleNameFilter.trim().isEmpty()) { + criteriaQuery + .where(builder.like(builder.lower(from.get("name")), + String.format("%s%%", roleNameFilter))); + } + + return entityManager + .createQuery(criteriaQuery) + .setMaxResults(query.getLimit()) + .setFirstResult(query.getOffset()) + .getResultList() + .stream(); + } + + public void setRoleNameFilter(final String roleNameFilter) { + this.roleNameFilter = roleNameFilter; + refreshAll(); + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UsersGroupsRoles.java b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UsersGroupsRoles.java index bb18e6cb0..3fb4267e4 100644 --- a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UsersGroupsRoles.java +++ b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UsersGroupsRoles.java @@ -56,9 +56,11 @@ public class UsersGroupsRoles extends CustomComponent { private final UsersTable usersTable; private final GroupsTable groupsTable; + private final RolesTable rolesTable; private UsersTableDataProvider usersTableDataProvider; private GroupsTableDataProvider groupsTableDataProvider; + private RolesTableDataProvider rolesTableDataProvider; public UsersGroupsRoles(final AdminView view) { @@ -167,9 +169,13 @@ public class UsersGroupsRoles extends CustomComponent { groupsTable = new GroupsTable(view, this); groupsTable.setWidth("100%"); + + rolesTable = new RolesTable(view, this); + rolesTable.setWidth("100%"); tabSheet.addTab(usersTable, "Users"); tabSheet.addTab(groupsTable, "Groups"); + tabSheet.addTab(rolesTable, "Roles"); setCompositionRoot(tabSheet); @@ -214,17 +220,30 @@ public class UsersGroupsRoles extends CustomComponent { } public void setUsersTableDataProvider(final UsersTableDataProvider dataProvider) { - this.usersTableDataProvider = dataProvider; + usersTableDataProvider = dataProvider; usersTable.setDataProvider(dataProvider); } public void setGroupsTableDataProvider(final GroupsTableDataProvider dataProvider) { - this.groupsTableDataProvider = dataProvider; + groupsTableDataProvider = dataProvider; groupsTable.setDataProvider(dataProvider); } + public void setRolesTableDataProvider(final RolesTableDataProvider dataProvider) { + rolesTableDataProvider = dataProvider; + rolesTable.setDataProvider(dataProvider); + } + protected void refreshUsers() { usersTableDataProvider.refreshAll(); } + protected void refreshGroups() { + groupsTableDataProvider.refreshAll(); + } + + protected void refreshRoles() { + rolesTableDataProvider.refreshAll(); + } + } diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UsersTableDataProvider.java b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UsersTableDataProvider.java index dafc37946..2a0113ed4 100644 --- a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UsersTableDataProvider.java +++ b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UsersTableDataProvider.java @@ -25,7 +25,6 @@ import org.libreccm.security.User; import java.util.stream.Stream; -import javax.enterprise.context.RequestScoped; import javax.inject.Inject; import javax.persistence.EntityManager; import javax.persistence.criteria.CriteriaBuilder; 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 3933e2b3c..7cd26619e 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 @@ -577,3 +577,5 @@ ui.admin.no=No ui.admin.user_form.email_malformed=This email address is malformed. ui.admin.user_edit.password_options.do_nothing=Do not change password ui.admin.user_form.failed_to_send_password_challenge=Failed to send password challenge to user. +ui.admin.groups.table.edit=Edit +ui.admin.roles.table.edit=Edit 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 f7ac25f28..634856988 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 @@ -581,3 +581,5 @@ ui.admin.no=Nein ui.admin.user_form.email_malformed=E-Mail Adresse ist fehlerhaft. ui.admin.user_edit.password_options.do_nothing=Password nicht ver\u00e4ndern ui.admin.user_form.failed_to_send_password_challenge=Beim Senden des Passwortes ist ein Fehler aufgetreten. +ui.admin.groups.table.edit=Bearbeiten +ui.admin.roles.table.edit=Bearbeiten 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 d1b045161..47a939e15 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 @@ -574,3 +574,5 @@ ui.admin.no=No ui.admin.user_form.email_malformed=This email address is malformed. ui.admin.user_edit.password_options.do_nothing=Do not change password ui.admin.user_form.failed_to_send_password_challenge=Failed to send password challenge to user. +ui.admin.groups.table.edit=Edit +ui.admin.roles.table.edit=Edit 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 3539f8352..3f51d2776 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 @@ -565,3 +565,5 @@ ui.admin.no=No ui.admin.user_form.email_malformed=This email address is malformed. ui.admin.user_edit.password_options.do_nothing=Do not change password ui.admin.user_form.failed_to_send_password_challenge=Failed to send password challenge to user. +ui.admin.groups.table.edit=Edit +ui.admin.roles.table.edit=Edit