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
jensp 2017-05-19 18:11:24 +00:00
parent 97a98c6a9b
commit be14263177
17 changed files with 444 additions and 68 deletions

View File

@ -19,9 +19,9 @@
package com.arsdigita.cms.contenttypes.ui; package com.arsdigita.cms.contenttypes.ui;
import com.arsdigita.bebop.Component; import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.cms.ItemSelectionModel; import com.arsdigita.cms.ItemSelectionModel;
import org.librecms.contenttypes.Article;
import com.arsdigita.cms.ui.authoring.AuthoringKitWizard; import com.arsdigita.cms.ui.authoring.AuthoringKitWizard;
import com.arsdigita.cms.ui.authoring.BasicPageForm; 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 * The name of the editing sheet added to this step
*/ */
public final static String EDIT_SHEET_NAME = "edit"; public final static String EDIT_SHEET_NAME = "edit";
private StringParameter selectedLanuageParam;
public ArticlePropertiesStep(ItemSelectionModel itemModel, public ArticlePropertiesStep(final ItemSelectionModel itemModel,
AuthoringKitWizard parent) { final AuthoringKitWizard parent,
super(itemModel, parent); final StringParameter selectedLanguageParam) {
super(itemModel, parent, selectedLanguageParam);
} }
@Override @Override

View File

@ -30,7 +30,6 @@ import com.arsdigita.bebop.parameters.ParameterModel;
import com.arsdigita.bebop.parameters.StringInRangeValidationListener; import com.arsdigita.bebop.parameters.StringInRangeValidationListener;
import com.arsdigita.bebop.parameters.StringParameter; import com.arsdigita.bebop.parameters.StringParameter;
import org.librecms.contentsection.ContentSection;
import com.arsdigita.cms.ItemSelectionModel; import com.arsdigita.cms.ItemSelectionModel;
import com.arsdigita.globalization.GlobalizedMessage; import com.arsdigita.globalization.GlobalizedMessage;

View File

@ -20,8 +20,9 @@ package com.arsdigita.cms.contenttypes.ui;
import com.arsdigita.bebop.Component; import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.PageState; 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.cms.ItemSelectionModel;
import com.arsdigita.toolbox.ui.DomainObjectPropertySheet; import com.arsdigita.toolbox.ui.DomainObjectPropertySheet;
@ -51,11 +52,16 @@ public class GenericArticlePropertiesStep extends SimpleEditStep {
public static final String EDIT_SHEET_NAME = "edit"; public static final String EDIT_SHEET_NAME = "edit";
private DomainObjectPropertySheet domainObjectPropertySheet; private DomainObjectPropertySheet domainObjectPropertySheet;
private StringParameter selectedLanguageParam;
public GenericArticlePropertiesStep(final ItemSelectionModel itemModel, public GenericArticlePropertiesStep(
final AuthoringKitWizard parent) { final ItemSelectionModel itemModel,
final AuthoringKitWizard parent,
final StringParameter selectedLanguageParam) {
super(itemModel, parent); super(itemModel, parent, selectedLanguageParam);
this.selectedLanguageParam = selectedLanguageParam;
setDefaultEditKey(EDIT_SHEET_NAME); setDefaultEditKey(EDIT_SHEET_NAME);
createEditSheet(itemModel); createEditSheet(itemModel);
@ -76,6 +82,10 @@ public class GenericArticlePropertiesStep extends SimpleEditStep {
setDisplayComponent(getGenericArticlePropertySheet(itemModel)); setDisplayComponent(getGenericArticlePropertySheet(itemModel));
} }
protected StringParameter getSelectedLanguageParam() {
return selectedLanguageParam;
}
/** /**
* Returns a component that displays the properties of the Article specified * Returns a component that displays the properties of the Article specified
* by the ItemSelectionModel passed in. * by the ItemSelectionModel passed in.

View File

@ -30,11 +30,9 @@ import org.librecms.contenttypes.Article;
import com.arsdigita.cms.ui.authoring.BasicPageForm; import com.arsdigita.cms.ui.authoring.BasicPageForm;
import org.apache.logging.log4j.LogManager;
import org.libreccm.cdi.utils.CdiUtil; import org.libreccm.cdi.utils.CdiUtil;
import org.librecms.contentsection.ContentItemRepository; 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 * Form to edit the basic properties of an article. This form can be extended to

View File

@ -36,6 +36,7 @@ import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormSectionEvent; import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.Label; import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.list.ListCellRenderer; import com.arsdigita.bebop.list.ListCellRenderer;
import com.arsdigita.bebop.parameters.StringParameter;
import org.librecms.contentsection.ContentType; import org.librecms.contentsection.ContentType;
@ -69,6 +70,7 @@ import org.apache.logging.log4j.LogManager;
import org.arsdigita.cms.CMSConfig; import org.arsdigita.cms.CMSConfig;
import org.libreccm.cdi.utils.CdiUtil; import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.configuration.ConfigurationManager; import org.libreccm.configuration.ConfigurationManager;
import org.libreccm.l10n.GlobalizationHelper;
import org.librecms.CmsConstants; import org.librecms.CmsConstants;
import org.librecms.contentsection.ContentItem; import org.librecms.contentsection.ContentItem;
import org.librecms.contenttypes.AuthoringKit; import org.librecms.contenttypes.AuthoringKit;
@ -99,18 +101,23 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
/** /**
* Private Logger instance for this class * Private Logger instance for this class
*/ */
private static final Logger LOGGER = LogManager.getLogger( private static final Logger LOGGER = LogManager
AuthoringKitWizard.class); .getLogger(AuthoringKitWizard.class);
public final String SELECTED_LANGUAGE = "selectedLanguage";
private static Class[] arguments = new Class[]{ private static Class[] arguments = new Class[]{
ItemSelectionModel.class, ItemSelectionModel.class,
AuthoringKitWizard.class AuthoringKitWizard.class,
StringParameter.class
}; };
private static Class[] userDefinedArgs = new Class[]{ private static Class[] userDefinedArgs = new Class[]{
ItemSelectionModel.class, ItemSelectionModel.class,
AuthoringKitWizard.class, AuthoringKitWizard.class,
ContentType.class ContentType.class
}; };
private static final java.util.List<AssetStepEntry> ASSETS = new ArrayList<AssetStepEntry>(); private static final java.util.List<AssetStepEntry> ASSETS
= new ArrayList<AssetStepEntry>();
private final Object[] values; private final Object[] values;
private final ContentTypeInfo typeInfo; private final ContentTypeInfo typeInfo;
private final AuthoringKitInfo kitInfo; private final AuthoringKitInfo kitInfo;
@ -125,6 +132,8 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
private final SimpleContainer stepsContainer; private final SimpleContainer stepsContainer;
private final TaskFinishForm m_taskFinishForm; private final TaskFinishForm m_taskFinishForm;
private final StringParameter selectedLanguageParam;
/** /**
* The name of the state parameter that determines whether the wizard is in * The name of the state parameter that determines whether the wizard is in
* item creation mode or item editing mode. * item creation mode or item editing mode.
@ -135,15 +144,17 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
*/ */
public static final String CREATION = "_creation_"; public static final String CREATION = "_creation_";
private final static String SEC_PAGE_EDIT_DYN = "com.arsdigita.cms.ui.authoring.SecondaryPageEditDynamic"; private final static String SEC_PAGE_EDIT_DYN
private final static String PAGE_EDIT_DYN = "com.arsdigita.cms.ui.authoring.PageEditDynamic"; = "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 * Construct a new AuthoringKitWizard. Add all the steps in the authoring
* kit to the wizard. * kit to the wizard.
* *
* @param typeInfo The content type of the items that this wizard will * @param typeInfo The content type of the items that this wizard will
* handle * handle
* @param selectionModel * @param selectionModel
*/ */
public AuthoringKitWizard(final ContentTypeInfo typeInfo, public AuthoringKitWizard(final ContentTypeInfo typeInfo,
@ -153,12 +164,19 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final ConfigurationManager confManager = cdiUtil.findBean( 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; this.typeInfo = typeInfo;
kitInfo = typeInfo.getAuthoringKit(); kitInfo = typeInfo.getAuthoringKit();
this.selectionModel = selectionModel; this.selectionModel = selectionModel;
values = new Object[]{selectionModel, this}; values = new Object[]{selectionModel, this, selectedLanguageParam};
workflowRequestLocal = new ItemWorkflowRequestLocal(); workflowRequestLocal = new ItemWorkflowRequestLocal();
labels = new SequentialMap(); labels = new SequentialMap();
@ -198,6 +216,7 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
} }
return new ControlLink(label); return new ControlLink(label);
} }
}); });
bodyPanel = new ModalPanel(); bodyPanel = new ModalPanel();
@ -208,17 +227,17 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
bodyPanel.setDefault(stepsContainer); bodyPanel.setDefault(stepsContainer);
final java.util.List<AuthoringStepInfo> steps = kitInfo. final java.util.List<AuthoringStepInfo> steps = kitInfo.
getAuthoringSteps(); getAuthoringSteps();
if (Assert.isEnabled()) { if (Assert.isEnabled()) {
Assert.isTrue(!steps.isEmpty(), Assert.isTrue(!steps.isEmpty(),
String.format("The authoring kit for content type " String.format("The authoring kit for content type "
+ "s\"%s\" has no steps.", + "s\"%s\" has no steps.",
typeInfo.getContentItemClass().getName())); typeInfo.getContentItemClass().getName()));
} }
final CMSConfig cmsConfig = confManager.findConfiguration( final CMSConfig cmsConfig = confManager.findConfiguration(
CMSConfig.class); CMSConfig.class);
StepComponent panel = null; StepComponent panel = null;
for (final AuthoringStepInfo step : steps) { for (final AuthoringStepInfo step : steps) {
@ -233,16 +252,16 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
* compatibility * compatibility
*/ */
final ResourceBundle labelBundle = ResourceBundle.getBundle(step. final ResourceBundle labelBundle = ResourceBundle.getBundle(step.
getLabelBundle()); getLabelBundle());
final ResourceBundle descBundle = ResourceBundle.getBundle(step. final ResourceBundle descBundle = ResourceBundle.getBundle(step.
getDescriptionBundle()); getDescriptionBundle());
final String labelKey = step.getLabelKey(); final String labelKey = step.getLabelKey();
final String label = labelBundle.getString(labelKey); final String label = labelBundle.getString(labelKey);
final String descriptionKey = step.getDescriptionKey(); final String descriptionKey = step.getDescriptionKey();
final String description = descBundle.getString(descriptionKey); final String description = descBundle.getString(descriptionKey);
final Class<? extends Component> componentClass = step. final Class<? extends Component> componentClass = step.
getComponent(); getComponent();
final String compClassName = componentClass.getName(); final String compClassName = componentClass.getName();
if (panel != null) { if (panel != null) {
@ -253,7 +272,7 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
final Component comp; final Component comp;
if (compClassName.equals(SEC_PAGE_EDIT_DYN) if (compClassName.equals(SEC_PAGE_EDIT_DYN)
|| compClassName.equals(PAGE_EDIT_DYN)) { || compClassName.equals(PAGE_EDIT_DYN)) {
comp = instantiateUserDefinedStep(compClassName, typeInfo); comp = instantiateUserDefinedStep(compClassName, typeInfo);
} else { } else {
comp = instantiateStep(compClassName); comp = instantiateStep(compClassName);
@ -262,7 +281,7 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
// XXX should be optional // XXX should be optional
if (comp instanceof AuthoringStepComponent) { if (comp instanceof AuthoringStepComponent) {
((AuthoringStepComponent) comp).addCompletionListener( ((AuthoringStepComponent) comp).addCompletionListener(
new StepCompletionListener()); new StepCompletionListener());
} }
final GlobalizedMessage gzLabel; final GlobalizedMessage gzLabel;
@ -283,8 +302,8 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
} }
} }
final Class<? extends ContentItem> typeClass = typeInfo. final Class<? extends ContentItem> typeClass = typeInfo
getContentItemClass(); .getContentItemClass();
final java.util.List<String> skipSteps = cmsConfig.getSkipAssetSteps(); final java.util.List<String> skipSteps = cmsConfig.getSkipAssetSteps();
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
@ -320,7 +339,7 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
Component comp = instantiateStep(step.getName()); Component comp = instantiateStep(step.getName());
if (comp instanceof AuthoringStepComponent) { if (comp instanceof AuthoringStepComponent) {
((AuthoringStepComponent) comp).addCompletionListener( ((AuthoringStepComponent) comp).addCompletionListener(
new StepCompletionListener()); new StepCompletionListener());
} }
panel.add(comp); panel.add(comp);
@ -340,11 +359,12 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
@Override @Override
public final void process(final FormSectionEvent event) public final void process(final FormSectionEvent event)
throws FormProcessException { throws FormProcessException {
final PageState state = event.getPageState(); final PageState state = event.getPageState();
assignedTaskTable.getRowSelectionModel().clearSelection(state); 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(); Object nextStep = step.getNextStepKey();
if (nextStep != null) { if (nextStep != null) {
list.getSelectionModel().setSelectedKey( list.getSelectionModel().setSelectedKey(
state, nextStep.toString()); state, nextStep.toString());
} }
} }
} }
} }
} }
} }
@Override @Override
@ -416,13 +438,14 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
if (state.isVisibleOnPage(AuthoringKitWizard.this)) { if (state.isVisibleOnPage(AuthoringKitWizard.this)) {
final SingleSelectionModel model = list. final SingleSelectionModel model = list.
getSelectionModel(); getSelectionModel();
if (!model.isSelected(state)) { if (!model.isSelected(state)) {
model.setSelectedKey(state, defaultKey); 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 // 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 // runs after original ccm-ldn-image-step initializer and override the registered step here
LOGGER.debug("registering asset step - label: \"{}\"; " LOGGER.debug("registering asset step - label: \"{}\"; "
+ "step class: \"%s\"", + "step class: \"%s\"",
label.localize(), label.localize(),
step.getName()); step.getName());
@ -456,16 +479,16 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
* *
*/ */
if ((thisObjectType.equals(baseObjectType)) if ((thisObjectType.equals(baseObjectType))
&& (thisLabel.localize().equals(label.localize()))) { && (thisLabel.localize().equals(label.localize()))) {
LOGGER.debug( 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); ASSETS.remove(data);
break; break;
} }
} }
ASSETS.add( ASSETS.add(
new AssetStepEntry(baseObjectType, step, label, description, new AssetStepEntry(baseObjectType, step, label, description,
sortKey)); sortKey));
Collections.sort(ASSETS); Collections.sort(ASSETS);
} }
@ -541,6 +564,7 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
return sortKey.compareTo(other.getSortKey()); return sortKey.compareTo(other.getSortKey());
} }
} }
} }
/** /**
@ -573,6 +597,7 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
* RuntimeException on failure. * RuntimeException on failure.
* *
* @param className The Java class name of the step * @param className The Java class name of the step
*
* @return The instance of the component. * @return The instance of the component.
*/ */
protected Component instantiateStep(final String className) { protected Component instantiateStep(final String className) {
@ -589,15 +614,15 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
return component; return component;
} catch (ClassNotFoundException } catch (ClassNotFoundException
| IllegalAccessException | IllegalAccessException
| IllegalArgumentException | IllegalArgumentException
| InstantiationException | InstantiationException
| InvocationTargetException | InvocationTargetException
| NoSuchMethodException | NoSuchMethodException
| SecurityException ex) { | SecurityException ex) {
throw new UncheckedWrapperException(String.format( throw new UncheckedWrapperException(String.format(
"Failed to instantiate authoring kit component \"{}\".", "Failed to instantiate authoring kit component \"{}\".",
className), className),
ex); ex);
} }
} }
@ -606,29 +631,30 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
* Instantiate the specified authoring kit step for a user defined content * Instantiate the specified authoring kit step for a user defined content
* type. Will throw a RuntimeException on failure. * 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 * @param originatingType
*
* @return * @return
*/ */
protected Component instantiateUserDefinedStep( protected Component instantiateUserDefinedStep(
final String className, final ContentTypeInfo originatingType) { final String className, final ContentTypeInfo originatingType) {
Object[] vals; Object[] vals;
try { try {
// Get the creation component // Get the creation component
final Class createClass = Class.forName(className); final Class createClass = Class.forName(className);
final Constructor constr = createClass.getConstructor( final Constructor constr = createClass.getConstructor(
userDefinedArgs); userDefinedArgs);
final Object[] userDefinedVals = new Object[]{selectionModel, final Object[] userDefinedVals = new Object[]{selectionModel,
this, this,
originatingType}; originatingType};
final Component component = (Component) constr.newInstance( final Component component = (Component) constr.newInstance(
userDefinedVals); userDefinedVals);
return component; return component;
} catch (ClassNotFoundException | NoSuchMethodException } catch (ClassNotFoundException | NoSuchMethodException
| InstantiationException | IllegalAccessException | InstantiationException | IllegalAccessException
| InvocationTargetException ex) { | InvocationTargetException ex) {
throw new UncheckedWrapperException(ex); throw new UncheckedWrapperException(ex);
} }
} }
@ -661,6 +687,7 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
public void setNextStepKey(final Object nextKey) { public void setNextStepKey(final Object nextKey) {
this.nextKey = nextKey; this.nextKey = nextKey;
} }
} }
private final class TaskSelectionRequestLocal extends TaskRequestLocal { private final class TaskSelectionRequestLocal extends TaskRequestLocal {
@ -668,12 +695,13 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
@Override @Override
protected final Object initialValue(final PageState state) { protected final Object initialValue(final PageState state) {
final String key = assignedTaskTable final String key = assignedTaskTable
.getRowSelectionModel() .getRowSelectionModel()
.getSelectedKey(state) .getSelectedKey(state)
.toString(); .toString();
return CmsTaskType.valueOf(key); return CmsTaskType.valueOf(key);
} }
} }
protected final static GlobalizedMessage gz(final String 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) { protected final static String lz(final String key) {
return (String) gz(key).localize(); return (String) gz(key).localize();
} }
} }

View File

@ -73,6 +73,8 @@ public class SimpleEditStep extends SecurityPropertyEditor
private StringParameter streamlinedCreationParameter; private StringParameter streamlinedCreationParameter;
private static final String STREAMLINED = "_streamlined"; private static final String STREAMLINED = "_streamlined";
private static final String STREAMLINED_DONE = "1"; private static final String STREAMLINED_DONE = "1";
private final StringParameter selectedLanguageParameter;
private static List<AdditionalDisplayComponent> additionalDisplayComponents private static List<AdditionalDisplayComponent> additionalDisplayComponents
= new ArrayList<>(); = new ArrayList<>();
@ -105,8 +107,9 @@ public class SimpleEditStep extends SecurityPropertyEditor
* stepBack, in its process listener. * stepBack, in its process listener.
*/ */
public SimpleEditStep(final ItemSelectionModel itemModel, public SimpleEditStep(final ItemSelectionModel itemModel,
final AuthoringKitWizard parent) { final AuthoringKitWizard parent,
this(itemModel, parent, ""); final StringParameter selectedLanguageParam) {
this(itemModel, parent, selectedLanguageParam, "");
} }
/** /**
@ -126,11 +129,14 @@ public class SimpleEditStep extends SecurityPropertyEditor
*/ */
public SimpleEditStep(final ItemSelectionModel itemSelectionModel, public SimpleEditStep(final ItemSelectionModel itemSelectionModel,
final AuthoringKitWizard authoringKitWizard, final AuthoringKitWizard authoringKitWizard,
final StringParameter selectedLanguageParam,
final String parameterSuffix) { final String parameterSuffix) {
super(); super();
this.authoringKitWizard = authoringKitWizard; this.authoringKitWizard = authoringKitWizard;
this.itemSelectionModel = itemSelectionModel; this.itemSelectionModel = itemSelectionModel;
this.selectedLanguageParameter = selectedLanguageParam;
streamlinedCreationParameter = new StringParameter( streamlinedCreationParameter = new StringParameter(
authoringKitWizard.getContentType().getContentItemClass().getName() authoringKitWizard.getContentType().getContentItemClass().getName()

View File

@ -22,13 +22,16 @@ import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.PropertySheet; import com.arsdigita.bebop.PropertySheet;
import com.arsdigita.bebop.PropertySheetModel; import com.arsdigita.bebop.PropertySheetModel;
import com.arsdigita.bebop.PropertySheetModelBuilder; import com.arsdigita.bebop.PropertySheetModelBuilder;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.globalization.GlobalizedMessage; import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.kernel.KernelConfig;
import com.arsdigita.toolbox.ToolboxConstants; import com.arsdigita.toolbox.ToolboxConstants;
import com.arsdigita.ui.CcmObjectSelectionModel; import com.arsdigita.ui.CcmObjectSelectionModel;
import com.arsdigita.util.LockableImpl; import com.arsdigita.util.LockableImpl;
import org.libreccm.core.CcmObject; import org.libreccm.core.CcmObject;
import org.libreccm.core.UnexpectedErrorException; import org.libreccm.core.UnexpectedErrorException;
import org.libreccm.l10n.LocalizedString;
import java.beans.BeanInfo; import java.beans.BeanInfo;
import java.beans.IntrospectionException; import java.beans.IntrospectionException;
@ -40,6 +43,7 @@ import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Optional; import java.util.Optional;
import java.util.StringTokenizer; import java.util.StringTokenizer;
@ -87,6 +91,8 @@ public class DomainObjectPropertySheet extends PropertySheet {
private AttributeFormatter toStringFormatter; private AttributeFormatter toStringFormatter;
private AttributeFormatter recursiveFormatter; private AttributeFormatter recursiveFormatter;
private StringParameter selectedLanguageParam;
/** /**
* Construct a new DomainObjectPropertySheet * Construct a new DomainObjectPropertySheet
* *
@ -111,10 +117,19 @@ public class DomainObjectPropertySheet extends PropertySheet {
final CcmObjectSelectionModel<?> objectSelectionModel, final CcmObjectSelectionModel<?> objectSelectionModel,
final boolean valueOutputEscape) { final boolean valueOutputEscape) {
this(objectSelectionModel, valueOutputEscape, null);
}
public DomainObjectPropertySheet(
final CcmObjectSelectionModel<?> objectSelectionModel,
final boolean valueOutputEscape,
final StringParameter selectedLanguageParam) {
super(new DomainObjectModelBuilder(), valueOutputEscape); super(new DomainObjectModelBuilder(), valueOutputEscape);
this.objectSelectionModel = objectSelectionModel; this.objectSelectionModel = objectSelectionModel;
properties = new LinkedList<>(); properties = new LinkedList<>();
this.selectedLanguageParam = selectedLanguageParam;
toStringFormatter = new SimpleAttributeFormatter(); toStringFormatter = new SimpleAttributeFormatter();
recursiveFormatter = new RecursiveAttributeFormatter(); recursiveFormatter = new RecursiveAttributeFormatter();
@ -481,7 +496,9 @@ public class DomainObjectPropertySheet extends PropertySheet {
return (String) defaultMsg.localize(); return (String) defaultMsg.localize();
} }
final Optional<Object> value = getPropertyValue(obj, attribute); final Optional<Object> value = getPropertyValue(obj,
attribute,
state);
if (value.isPresent()) { if (value.isPresent()) {
return value.get().toString(); return value.get().toString();
@ -544,7 +561,7 @@ public class DomainObjectPropertySheet extends PropertySheet {
while (tokenizer.hasMoreTokens()) { while (tokenizer.hasMoreTokens()) {
token = tokenizer.nextToken(); token = tokenizer.nextToken();
// Null check // Null check
currentObject = getPropertyValue(currentObject, token); currentObject = getPropertyValue(currentObject, token, state);
if (currentObject == null) { if (currentObject == null) {
return (String) getDefaultValue().localize(); return (String) getDefaultValue().localize();
} }
@ -561,7 +578,8 @@ public class DomainObjectPropertySheet extends PropertySheet {
} }
private Optional<Object> getPropertyValue(final Object obj, private Optional<Object> getPropertyValue(final Object obj,
final String property) { final String property,
final PageState state) {
final BeanInfo beanInfo; final BeanInfo beanInfo;
try { try {
@ -583,7 +601,23 @@ public class DomainObjectPropertySheet extends PropertySheet {
final Object value; final Object value;
try { 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) { } catch (IllegalAccessException | InvocationTargetException ex) {
throw new UnexpectedErrorException(ex); throw new UnexpectedErrorException(ex);
} }

View File

@ -35,6 +35,7 @@ import com.vaadin.ui.TabSheet;
import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.VerticalLayout;
import org.apache.shiro.subject.Subject; import org.apache.shiro.subject.Subject;
import org.libreccm.admin.ui.usersgroupsroles.GroupsTableDataProvider; 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.UsersGroupsRoles;
import org.libreccm.admin.ui.usersgroupsroles.UsersTableDataProvider; import org.libreccm.admin.ui.usersgroupsroles.UsersTableDataProvider;
import org.libreccm.l10n.GlobalizationHelper; import org.libreccm.l10n.GlobalizationHelper;
@ -87,6 +88,9 @@ public class AdminView extends CustomComponent implements View {
@Inject @Inject
private GroupsTableDataProvider groupsTableDataProvider; private GroupsTableDataProvider groupsTableDataProvider;
@Inject
private RolesTableDataProvider rolesTableDataProvider;
private ResourceBundle bundle; private ResourceBundle bundle;
@Inject @Inject
@ -173,6 +177,7 @@ public class AdminView extends CustomComponent implements View {
usersGroupsRoles.setUsersTableDataProvider(usersTableDataProvider); usersGroupsRoles.setUsersTableDataProvider(usersTableDataProvider);
usersGroupsRoles.setGroupsTableDataProvider(groupsTableDataProvider); usersGroupsRoles.setGroupsTableDataProvider(groupsTableDataProvider);
usersGroupsRoles.setRolesTableDataProvider(rolesTableDataProvider);
tabUsersGroupsRoles.setCaption(bundle tabUsersGroupsRoles.setCaption(bundle
.getString("ui.admin.tab.users_groups_roles.title")); .getString("ui.admin.tab.users_groups_roles.title"));

View File

@ -77,8 +77,8 @@ public class GroupsTable extends Grid<Group> {
final HeaderRow filterRow = appendHeaderRow(); final HeaderRow filterRow = appendHeaderRow();
final HeaderCell GroupNameFilterCell = filterRow.getCell(COL_NAME); final HeaderCell GroupNameFilterCell = filterRow.getCell(COL_NAME);
groupNameFilter = new TextField(); groupNameFilter = new TextField();
groupNameFilter.setPlaceholder("User name"); groupNameFilter.setPlaceholder("Group name");
groupNameFilter.setDescription("Filter Groups by Groupname"); groupNameFilter.setDescription("Filter Groups by name");
groupNameFilter.addStyleName(ValoTheme.TEXTFIELD_TINY); groupNameFilter.addStyleName(ValoTheme.TEXTFIELD_TINY);
groupNameFilter groupNameFilter
.addValueChangeListener(event -> { .addValueChangeListener(event -> {

View File

@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class RolesTable extends Grid<Role> {
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> 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"));
}
}

View File

@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@ViewScoped
public class RolesTableDataProvider extends AbstractDataProvider<Role, String> {
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<Role, String> query) {
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Long> criteriaQuery = builder.createQuery(Long.class);
final Root<Role> 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<Role> fetch(final Query<Role, String> query) {
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Role> criteriaQuery = builder.createQuery(Role.class);
final Root<Role> 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();
}
}

View File

@ -56,9 +56,11 @@ public class UsersGroupsRoles extends CustomComponent {
private final UsersTable usersTable; private final UsersTable usersTable;
private final GroupsTable groupsTable; private final GroupsTable groupsTable;
private final RolesTable rolesTable;
private UsersTableDataProvider usersTableDataProvider; private UsersTableDataProvider usersTableDataProvider;
private GroupsTableDataProvider groupsTableDataProvider; private GroupsTableDataProvider groupsTableDataProvider;
private RolesTableDataProvider rolesTableDataProvider;
public UsersGroupsRoles(final AdminView view) { public UsersGroupsRoles(final AdminView view) {
@ -167,9 +169,13 @@ public class UsersGroupsRoles extends CustomComponent {
groupsTable = new GroupsTable(view, this); groupsTable = new GroupsTable(view, this);
groupsTable.setWidth("100%"); groupsTable.setWidth("100%");
rolesTable = new RolesTable(view, this);
rolesTable.setWidth("100%");
tabSheet.addTab(usersTable, "Users"); tabSheet.addTab(usersTable, "Users");
tabSheet.addTab(groupsTable, "Groups"); tabSheet.addTab(groupsTable, "Groups");
tabSheet.addTab(rolesTable, "Roles");
setCompositionRoot(tabSheet); setCompositionRoot(tabSheet);
@ -214,17 +220,30 @@ public class UsersGroupsRoles extends CustomComponent {
} }
public void setUsersTableDataProvider(final UsersTableDataProvider dataProvider) { public void setUsersTableDataProvider(final UsersTableDataProvider dataProvider) {
this.usersTableDataProvider = dataProvider; usersTableDataProvider = dataProvider;
usersTable.setDataProvider(dataProvider); usersTable.setDataProvider(dataProvider);
} }
public void setGroupsTableDataProvider(final GroupsTableDataProvider dataProvider) { public void setGroupsTableDataProvider(final GroupsTableDataProvider dataProvider) {
this.groupsTableDataProvider = dataProvider; groupsTableDataProvider = dataProvider;
groupsTable.setDataProvider(dataProvider); groupsTable.setDataProvider(dataProvider);
} }
public void setRolesTableDataProvider(final RolesTableDataProvider dataProvider) {
rolesTableDataProvider = dataProvider;
rolesTable.setDataProvider(dataProvider);
}
protected void refreshUsers() { protected void refreshUsers() {
usersTableDataProvider.refreshAll(); usersTableDataProvider.refreshAll();
} }
protected void refreshGroups() {
groupsTableDataProvider.refreshAll();
}
protected void refreshRoles() {
rolesTableDataProvider.refreshAll();
}
} }

View File

@ -25,7 +25,6 @@ import org.libreccm.security.User;
import java.util.stream.Stream; import java.util.stream.Stream;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject; import javax.inject.Inject;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaBuilder;

View File

@ -577,3 +577,5 @@ ui.admin.no=No
ui.admin.user_form.email_malformed=This email address is malformed. 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_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.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

View File

@ -581,3 +581,5 @@ ui.admin.no=Nein
ui.admin.user_form.email_malformed=E-Mail Adresse ist fehlerhaft. 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_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.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

View File

@ -574,3 +574,5 @@ ui.admin.no=No
ui.admin.user_form.email_malformed=This email address is malformed. 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_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.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

View File

@ -565,3 +565,5 @@ ui.admin.no=No
ui.admin.user_form.email_malformed=This email address is malformed. 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_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.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