- First part of RelatedInfoStep
- Some other things


git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4905 8810af33-2d31-482b-a856-94f89814c4df
jensp 2017-08-16 16:39:32 +00:00
parent b89b3c864c
commit 2021628b8e
30 changed files with 1112 additions and 55 deletions

View File

@ -116,8 +116,7 @@ public abstract class AbstractAssetForm<T extends Asset>
}
}
}
);
});
showLocaleSelect = new SingleSelect("selected-locale");
try {
showLocaleSelect.addPrintListener(new PrintListener() {
@ -139,9 +138,8 @@ public abstract class AbstractAssetForm<T extends Asset>
final List<Locale> availableLocales = new ArrayList<>(
l10nManager.availableLocales(selectedAsset.get()));
availableLocales.sort((locale1, locale2) -> {
return locale1
.toString()
.compareTo(locale2.toString());
return locale1.toString().compareTo(locale2
.toString());
});
availableLocales.forEach(locale -> target.addOption(
new Option(locale.toString(),
@ -301,10 +299,7 @@ public abstract class AbstractAssetForm<T extends Asset>
if (selectedAsset.isPresent()) {
showLocaleSelect.setValue(state,
KernelConfig
.getConfig()
.getDefaultLocale()
.toString());
getSelectedLocale(state));
title.setValue(state,
selectedAsset

View File

@ -0,0 +1,106 @@
/*
* 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 com.arsdigita.cms.ui.authoring.assets;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.ParameterSingleSelectionModel;
import com.arsdigita.bebop.SingleSelectionModel;
import com.arsdigita.bebop.event.ChangeListener;
import com.arsdigita.bebop.parameters.LongParameter;
import com.arsdigita.bebop.parameters.ParameterModel;
import org.libreccm.cdi.utils.CdiUtil;
import org.librecms.contentsection.AttachmentList;
import org.librecms.contentsection.AttachmentListManager;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class AttachmentListSelectionModel implements
SingleSelectionModel<Long> {
private final SingleSelectionModel<Long> model;
public AttachmentListSelectionModel(final LongParameter parameter) {
this.model = new ParameterSingleSelectionModel<>(parameter);
}
public AttachmentListSelectionModel(final String parameterName) {
this(new LongParameter(parameterName));
}
@Override
public boolean isSelected(final PageState state) {
return model.isSelected(state);
}
@Override
public Long getSelectedKey(final PageState state) {
final Object key = model.getSelectedKey(state);
if (key == null) {
return null;
} else if (key instanceof Long) {
return (Long) key;
} else if (key instanceof String) {
return Long.parseLong((String) key);
} else {
return Long.parseLong(key.toString());
}
}
@Override
public void setSelectedKey(final PageState state,
final Long key) {
model.setSelectedKey(state, key);
}
public AttachmentList getSelectedAttachmentList(final PageState state) {
final Long key = getSelectedKey(state);
if (key == null) {
return null;
} else {
final AttachmentListManager manager = CdiUtil
.createCdiUtil()
.findBean(AttachmentListManager.class);
return manager.getAttachmentList(key).get();
}
}
@Override
public void clearSelection(final PageState state) {
model.clearSelection(state);
}
@Override
public void addChangeListener(final ChangeListener changeListener) {
model.addChangeListener(changeListener);
}
@Override
public void removeChangeListener(final ChangeListener changeListener) {
model.removeChangeListener(changeListener);
}
@Override
public ParameterModel getStateParameter() {
return model.getStateParameter();
}
}

View File

@ -0,0 +1,377 @@
/*
* 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 com.arsdigita.cms.ui.authoring.assets.relatedinfo;
import com.arsdigita.bebop.BoxPanel;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SaveCancelSection;
import com.arsdigita.bebop.Text;
import com.arsdigita.bebop.event.FormInitListener;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.event.FormSubmissionListener;
import com.arsdigita.bebop.form.Option;
import com.arsdigita.bebop.form.SingleSelect;
import com.arsdigita.bebop.form.Submit;
import com.arsdigita.bebop.form.TextArea;
import com.arsdigita.bebop.form.TextField;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.cms.ItemSelectionModel;
import com.arsdigita.cms.ui.authoring.assets.AttachmentListSelectionModel;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.kernel.KernelConfig;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.core.UnexpectedErrorException;
import org.librecms.CmsConstants;
import org.librecms.contentsection.AttachmentList;
import org.librecms.contentsection.AttachmentListL10NManager;
import org.librecms.contentsection.AttachmentListManager;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.TooManyListenersException;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
class RelatedInfoListForm
extends Form
implements FormInitListener,
FormProcessListener,
FormSubmissionListener {
private final RelatedInfoStep relatedInfoStep;
private final ItemSelectionModel itemSelectionModel;
private final AttachmentListSelectionModel listSelectionModel;
private final StringParameter selectedLanguage;
private BoxPanel showLocalePanel;
private SingleSelect showLocaleSelect;
private Submit showLocaleSubmit;
private BoxPanel addLocalePanel;
private SingleSelect addLocaleSelect;
private Submit addLocaleSubmit;
private TextField nameField;
private TextField titleField;
private TextArea descriptionArea;
private SaveCancelSection saveCancelSection;
public RelatedInfoListForm(
final RelatedInfoStep relatedInfoStep,
final ItemSelectionModel itemSelectionModel,
final AttachmentListSelectionModel listSelectionModel,
final StringParameter selectedLanguageParam) {
super("relatedinfo-list-form", new BoxPanel(BoxPanel.VERTICAL));
this.relatedInfoStep = relatedInfoStep;
this.itemSelectionModel = itemSelectionModel;
this.listSelectionModel = listSelectionModel;
this.selectedLanguage = selectedLanguageParam;
showLocalePanel = new BoxPanel(BoxPanel.HORIZONTAL);
final Label showLocaleLabel = new Label(event -> {
final PageState state = event.getPageState();
final Optional<AttachmentList> selectedList = getSelectedList(state);
final Label target = (Label) event.getTarget();
if (selectedList.isPresent()) {
target.setLabel(new GlobalizedMessage(
"cms.ui.assetlist.show_locale",
CmsConstants.CMS_BUNDLE));
} else {
target.setLabel(new GlobalizedMessage(
"cms.ui.assetlist.initial_locale",
CmsConstants.CMS_BUNDLE));
}
});
showLocaleSelect = new SingleSelect("selected-locale");
try {
showLocaleSelect.addPrintListener(event -> {
final PageState state = event.getPageState();
final Optional<AttachmentList> selectedList = getSelectedList(
state);
if (selectedList.isPresent()) {
final SingleSelect target = (SingleSelect) event.getTarget();
target.clearOptions();;
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final AttachmentListL10NManager l10NManager = cdiUtil
.findBean(AttachmentListL10NManager.class);
final List<Locale> availableLocales = new ArrayList<>(
l10NManager.availableLocales(selectedList.get()));
availableLocales.sort((locale1, locale2) -> {
return locale1.toString().compareTo(locale2.toString());
});
availableLocales.forEach(locale -> target.addOption(
new Option(locale.toString(),
new Text(locale.toString()))));
} else {
final SingleSelect target = (SingleSelect) event
.getTarget();
target.clearOptions();
final List<String> langs = new ArrayList<>(
KernelConfig.getConfig().getSupportedLanguages());
langs.sort((lang1, lang2) -> lang1.compareTo(lang2));
langs.forEach(lang -> {
target.addOption(new Option(lang, new Text(lang)));
});
}
});
} catch (TooManyListenersException ex) {
throw new UnexpectedErrorException(ex);
}
showLocaleSubmit = new Submit(new GlobalizedMessage(
"cms.ui.assetlist.show_locale",
CmsConstants.CMS_BUNDLE)) {
@Override
public boolean isVisible(final PageState state) {
return getSelectedList(state).isPresent();
}
};
showLocalePanel.add(showLocaleLabel);
showLocalePanel.add(showLocaleSelect);
showLocalePanel.add(showLocaleSubmit);
super.add(showLocalePanel);
addLocalePanel = new BoxPanel(BoxPanel.HORIZONTAL) {
@Override
public boolean isVisible(final PageState state) {
return getSelectedList(state).isPresent();
}
};
final Label addLocaleLabel = new Label(
new GlobalizedMessage("cms.ui.assetlist.add_locale",
CmsConstants.CMS_BUNDLE));
addLocaleSelect = new SingleSelect("add-locale-select");
try {
addLocaleSelect.addPrintListener(event -> {
final PageState state = event.getPageState();
final Optional<AttachmentList> selectedList = getSelectedList(
state);
if (selectedList.isPresent()) {
final SingleSelect target = (SingleSelect) event.getTarget();
target.clearOptions();
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final AttachmentListL10NManager l10nManager = cdiUtil
.findBean(AttachmentListL10NManager.class);
final List<Locale> creatableLocales = new ArrayList<>(
l10nManager.creatableLocales(selectedList.get()));
creatableLocales.sort((locale1, locale2) -> {
return locale1
.toString()
.compareTo(locale2.toString());
});
creatableLocales.forEach(locale -> target.addOption(
new Option(locale.toString(),
new Text(locale.toString()))));
}
});
} catch (TooManyListenersException ex) {
throw new UnexpectedErrorException(ex);
}
addLocaleSubmit = new Submit(new GlobalizedMessage(
"cms.ui.assetlist.add_locale",
CmsConstants.CMS_BUNDLE));
addLocalePanel.add(addLocaleLabel);
addLocalePanel.add(addLocaleSelect);
addLocalePanel.add(addLocaleSubmit);
super.add(addLocalePanel);
super.add(new Label(new GlobalizedMessage("cms.ui.assetlist.name",
CmsConstants.CMS_BUNDLE)));
nameField = new TextField("attachmentListName");
super.add(nameField);
super.add(new Label(new GlobalizedMessage("cms.ui.assetlist.title",
CmsConstants.CMS_BUNDLE)));
titleField = new TextField("attachmentListTitle");
super.add(titleField);
super.add(new Label(
new GlobalizedMessage("cms.ui.assetlist.description",
CmsConstants.CMS_BUNDLE)));
descriptionArea = new TextArea("attachmentListDesc");
super.add(descriptionArea);
saveCancelSection = new SaveCancelSection();
super.add(saveCancelSection);
super.addInitListener(this);
super.addProcessListener(this);
super.addSubmissionListener(this);
}
protected Optional<AttachmentList> getSelectedList(final PageState state) {
if (listSelectionModel.getSelectedKey(state) == null) {
return Optional.empty();
} else {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final AttachmentListManager manager = cdiUtil
.findBean(AttachmentListManager.class);
final AttachmentList list = manager
.getAttachmentList(listSelectionModel.getSelectedKey(state))
.orElseThrow(() -> new IllegalArgumentException(String
.format("No AttachmentList with ID %d in the database.",
listSelectionModel.getSelectedKey(state))));
return Optional.of(list);
}
}
@Override
public void init(final FormSectionEvent event) throws FormProcessException {
final PageState state = event.getPageState();
final Optional<AttachmentList> selectedList = getSelectedList(state);
if (selectedList.isPresent()) {
nameField.setValue(state, selectedList.get().getName());
showLocaleSelect.setValue(state,
KernelConfig
.getConfig()
.getDefaultLocale()
.toString());
titleField.setValue(state,
selectedList
.get()
.getTitle()
.getValue(getSelectedLocale(state)));
descriptionArea.setValue(state,
selectedList
.get()
.getTitle()
.getValue(getSelectedLocale(state)));
} else {
showLocaleSelect.setValue(state,
KernelConfig
.getConfig()
.getDefaultLocale()
.toString());
}
}
protected Locale getSelectedLocale(final PageState state) {
final String selected = (String) showLocaleSelect.getValue(state);
if (selected == null) {
return KernelConfig.getConfig().getDefaultLocale();
} else {
return new Locale(selected);
}
}
@Override
public void process(final FormSectionEvent event)
throws FormProcessException {
final PageState state = event.getPageState();
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
if (showLocaleSubmit.isSelected(state)) {
return;
}
if (addLocaleSubmit.isSelected(state)) {
final AttachmentListL10NManager l10nManager = cdiUtil
.findBean(AttachmentListL10NManager.class);
final Locale add = new Locale((String) addLocaleSelect
.getValue(state));
final Optional<AttachmentList> selectedList = getSelectedList(state);
l10nManager.addLanguage(selectedList.get(), add);
}
if (saveCancelSection.getSaveButton().isSelected(state)) {
final RelatedInfoStepController controller = cdiUtil
.findBean(RelatedInfoStepController.class);
final AttachmentListManager attachmentListManager = cdiUtil
.findBean(AttachmentListManager.class);
final Optional<AttachmentList> selectedList = getSelectedList(state);
final AttachmentList attachmentList;
if (selectedList.isPresent()) {
attachmentList = selectedList.get();
} else {
attachmentList = attachmentListManager
.createAttachmentList(itemSelectionModel
.getSelectedItem(state),
(String) nameField.getValue(state));
}
attachmentList.setName((String) nameField.getValue(state));
attachmentList
.getTitle()
.addValue(getSelectedLocale(state),
(String) titleField.getValue(state));
attachmentList
.getDescription()
.addValue(getSelectedLocale(state),
(String) descriptionArea.getValue(state));
controller.saveAttachmentList(attachmentList);
}
}
@Override
public void submitted(final FormSectionEvent event)
throws FormProcessException {
final PageState state = event.getPageState();
if (saveCancelSection.getCancelButton().isSelected(state)) {
listSelectionModel.clearSelection(state);
relatedInfoStep.showAttachmentList(state);
}
}
}

View File

@ -16,8 +16,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.cms.ui.authoring.assets;
package com.arsdigita.cms.ui.authoring.assets.relatedinfo;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.Text;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.cms.ItemSelectionModel;
@ -47,4 +48,8 @@ public class RelatedInfoStep extends ResettableContainer {
super.add(new Text("Related Info Step placeholder"));
}
protected void showAttachmentList(final PageState state) {
}
}

View File

@ -0,0 +1,49 @@
/*
* 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 com.arsdigita.cms.ui.authoring.assets.relatedinfo;
import org.librecms.contentsection.AttachmentList;
import org.librecms.contentsection.AttachmentListManager;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
class RelatedInfoStepController {
@Inject
private AttachmentListManager attachmentListManager;
@Inject
private EntityManager entityManager;
protected void saveAttachmentList(final AttachmentList attachmentList) {
if (attachmentList.getListId() == 0) {
entityManager.persist(attachmentList);
} else {
entityManager.merge(attachmentList);
}
}
}

View File

@ -51,7 +51,7 @@ import javax.inject.Inject;
import javax.transaction.Transactional;
/**
* Manages the language versions of an asset.
* Manages the language variants of an asset.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@ -159,7 +159,7 @@ public class AssetL10NManager {
* @param asset The asset to check.
* @param locale The locale to check for.
*
* @return {@link true} if the item has data for the language, {@code false}
* @return {@link true} if the asset has data for the language, {@code false}
* if not.
*/
@AuthorizationRequired
@ -184,7 +184,7 @@ public class AssetL10NManager {
*
* @param asset The asset.
*
* @return A {@link Set} with the locales for which the item does not have a
* @return A {@link Set} with the locales for which the asset does not have a
* variant.
*/
@Transactional(Transactional.TxType.REQUIRED)

View File

@ -0,0 +1,334 @@
/*
* Copyright (C) 2017 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.librecms.contentsection;
import com.arsdigita.kernel.KernelConfig;
import org.libreccm.configuration.ConfigurationManager;
import org.libreccm.core.UnexpectedErrorException;
import org.libreccm.l10n.LocalizedString;
import org.libreccm.security.AuthorizationRequired;
import org.libreccm.security.RequiresPrivilege;
import org.librecms.contentsection.privileges.AssetPrivileges;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.transaction.Transactional;
/**
* Manages the language variants of an {@link AttachmentList}.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class AttachmentListL10NManager {
@Inject
private ConfigurationManager confManager;
@Inject
private AttachmentListManager listManager;
@Inject
private EntityManager entityManager;
private Locale defaultLocale;
private List<Locale> supportedLocales;
@PostConstruct
private void init() {
final KernelConfig kernelConfig = confManager.findConfiguration(
KernelConfig.class);
defaultLocale = kernelConfig.getDefaultLocale();
supportedLocales = kernelConfig.getSupportedLanguages()
.stream()
.map(language -> new Locale(language))
.collect(Collectors.toList());
}
private List<PropertyDescriptor> findLocalizedStringProperties(
final AttachmentList attachmentList) {
try {
final PropertyDescriptor[] properties = Introspector
.getBeanInfo(attachmentList.getClass())
.getPropertyDescriptors();
return Arrays.stream(properties)
.filter(property -> {
return property
.getPropertyType()
.isAssignableFrom(LocalizedString.class);
})
.collect(Collectors.toList());
} catch (IntrospectionException ex) {
throw new UnexpectedErrorException(ex);
}
}
private LocalizedString readLocalizedString(
final AttachmentList attachmentList,
final Method readMethod) {
try {
return (LocalizedString) readMethod.invoke(attachmentList);
} catch (IllegalAccessException
| IllegalArgumentException
| InvocationTargetException ex) {
throw new UnexpectedErrorException(ex);
}
}
private Set<Locale> collectLanguages(final AttachmentList attachmentList) {
final Set<Locale> locales = new HashSet<>();
findLocalizedStringProperties(attachmentList)
.stream()
.map(property -> property.getReadMethod())
.map(readMethod -> readLocalizedString(attachmentList, readMethod))
.forEach(str -> locales.addAll(str.getAvailableLocales()));
return locales;
}
/**
* Retrieves all languages in which the describing properties of an {@link AttachmentList) are available.
*
* @param attachmentList The {@link AttachmentList}
*
* @return An (unmodifiable) {@link Set} containing all languages in which
* the attachment list is available.
*/
@Transactional(Transactional.TxType.REQUIRED)
public Set<Locale> availableLocales(final AttachmentList attachmentList) {
return Collections.unmodifiableSet(collectLanguages(attachmentList));
}
/**
* Checks if an {@link AttachmentList} has data for the particular language.
*
* @param attachmentList The AttachmentList to check.
* @param locale The locale to check for.
*
* @return {@link true} if the attachment list has data for the language,
* {@code false} if not.
*/
public boolean hasLanguage(final AttachmentList attachmentList,
final Locale locale) {
Objects.requireNonNull(
attachmentList,
"Can't check if AttachmentList null has a specific locale.");
Objects.requireNonNull(locale, "Can't check for locale null.");
return collectLanguages(attachmentList).contains(locale);
}
/**
* Returns a {@link Set} containing the locales for which the
* {@link AttachmentList} does not yet have a variant.
*
* @param attachmentList The {@link AttachmentList}.
*
* @return A {@link Set} with the locales for which the
* {@link AttachmentList} does not have a variant.
*/
@Transactional(Transactional.TxType.REQUIRED)
public Set<Locale> creatableLocales(final AttachmentList attachmentList) {
return supportedLocales.stream()
.filter(locale -> !hasLanguage(attachmentList, locale))
.collect(Collectors.toSet());
}
/**
* Adds a language to an {@link AttachmentList}. The method will retrieve
* all fields of the type {@link LocalizedString} from the
* {@link AttachmentList} and add a new entry for the provided locale by
* coping the value for the default language configured in
* {@link KernelConfig}. If a field does not have an entry for the default
* language the first value found is used.
*
* @param attachmentList The {@link AttachmentList} to which the language
* variant is added.
* @param locale The locale of the language to add.
*/
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public void addLanguage(
@RequiresPrivilege(AssetPrivileges.EDIT)
final AttachmentList attachmentList,
final Locale locale) {
Objects.requireNonNull(attachmentList,
"Can't add language to asset null.");
Objects.requireNonNull(attachmentList,
"Cant't add language null to an asset.");
findLocalizedStringProperties(attachmentList)
.forEach(property -> addLanguage(attachmentList, locale, property));
entityManager.merge(attachmentList);
}
private void addLanguage(final AttachmentList attachmentList,
final Locale locale,
final PropertyDescriptor property) {
final Method readMethod = property.getReadMethod();
final LocalizedString localizedStr = readLocalizedString(attachmentList,
readMethod);
addLanguage(localizedStr, locale);
}
private void addLanguage(final LocalizedString localizedString,
final Locale locale) {
if (localizedString.hasValue(locale)) {
//Nothing to do
return;
}
final String value;
if (localizedString.hasValue(defaultLocale)) {
value = localizedString.getValue(defaultLocale);
} else {
value = findValue(localizedString);
}
localizedString.addValue(locale, value);
}
private String findValue(final LocalizedString localizedStr) {
final Optional<Locale> locale = supportedLocales
.stream()
.filter(current -> localizedStr.hasValue(current))
.findAny();
if (locale.isPresent()) {
return localizedStr.getValue(locale.get());
} else {
return "Lorem ipsum";
}
}
/**
* Removes a language variant from an {@link AttachmentList}. This method
* will retrieve all fields of the type {@link LocalizedString} from the
* {@link AttachmentList} and remove the entry for the provided locale if
* the field has an entry for that locale.
*
* @param attachmentList
* @param locale
*/
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public void removeLanguage(
@RequiresPrivilege(AssetPrivileges.EDIT)
final AttachmentList attachmentList,
final Locale locale) {
Objects.requireNonNull(attachmentList,
"Can't remove language to attachmentList null.");
Objects
.requireNonNull(attachmentList,
"Cant't remove language null to an attachmentList.");
findLocalizedStringProperties(attachmentList)
.forEach(
property -> removeLanguage(attachmentList, locale, property));
entityManager.merge(attachmentList);
}
private void removeLanguage(final AttachmentList attachmentList,
final Locale locale,
final PropertyDescriptor property) {
final Method readMethod = property.getReadMethod();
final LocalizedString localizedStr = readLocalizedString(attachmentList,
readMethod);
if (localizedStr.hasValue(locale)) {
localizedStr.removeValue(locale);
}
}
/**
* This method normalises the values of the fields of type
* {@link LocalizedString} of an {@link AttachmentList}. The method will
* first retrieve all fields of the type {@link LocalizedString} from the
* {@link AttachmentList} and than build a set with all locales provided by
* any of the fields. After that the method will iterate over all
* {@link LocalizedString} fields and check if the {@link LocalizedString}
* has an entry for every language in the set. If not an entry for the
* language is added.
*
* @param attachmentList The attachmentList to normalise.
*/
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public void normalizeLanguages(
final AttachmentList attachmentList) {
Objects.requireNonNull(attachmentList,
"Can't normalise attachmentList null");
final Set<Locale> languages = collectLanguages(attachmentList);
findLocalizedStringProperties(attachmentList)
.stream()
.map(property -> property.getReadMethod())
.map(readMethod -> readLocalizedString(attachmentList, readMethod))
.forEach(str -> normalize(str, languages));
}
private void normalize(final LocalizedString localizedString,
final Set<Locale> languages) {
final List<Locale> missingLangs = languages.stream()
.filter(lang -> !localizedString.hasValue(lang))
.collect(Collectors.toList());
if (!missingLangs.isEmpty()) {
missingLangs.stream()
.forEach(lang -> addLanguage(localizedString, lang));
}
}
}

View File

@ -18,7 +18,7 @@
*/
package org.librecms.contentsection;
import com.arsdigita.cms.ui.authoring.assets.RelatedInfoStep;
import com.arsdigita.cms.ui.authoring.assets.relatedinfo.RelatedInfoStep;
import com.arsdigita.cms.ui.authoring.assets.images.ImageStep;
import org.libreccm.cdi.utils.CdiUtil;

View File

@ -414,3 +414,9 @@ cms.ui.authoring.assets.imagestep.available_images.title_header=Title
cms.ui.authoring.assets.imagestep.available_images.add=Add
cms.ui.authoring.assets.imagestep.assigned_images.title_header=Title
cms.ui.authoring.assets.imagestep.assigned_images.remove=Remove
cms.ui.assetlist.show_locale=Show data for locale
cms.ui.assetlist.initial_locale=Language
cms.ui.assetlist.add_locale=Add data for language
cms.ui.assetlist.name=Name
cms.ui.assetlist.title=Title
cms.ui.assetlist.description=Description

View File

@ -411,3 +411,9 @@ cms.ui.authoring.assets.imagestep.available_images.title_header=Titel
cms.ui.authoring.assets.imagestep.available_images.add=Hinzuf\u00fcgen
cms.ui.authoring.assets.imagestep.assigned_images.title_header=Titel
cms.ui.authoring.assets.imagestep.assigned_images.remove=Entfernen
cms.ui.assetlist.show_locale=Zeige Daten f\u00fcr Sprache
cms.ui.assetlist.initial_locale=Sprache
cms.ui.assetlist.add_locale=Daten f\u00fcr folgende Sprache hinzuf\u00fcgen
cms.ui.assetlist.name=Name
cms.ui.assetlist.title=Titel
cms.ui.assetlist.description=Beschreibung

View File

@ -370,3 +370,9 @@ cms.ui.authoring.assets.imagestep.available_images.title_header=Title
cms.ui.authoring.assets.imagestep.available_images.add=Add
cms.ui.authoring.assets.imagestep.assigned_images.title_header=Title
cms.ui.authoring.assets.imagestep.assigned_images.remove=Remove
cms.ui.assetlist.show_locale=Show data for locale
cms.ui.assetlist.initial_locale=Language
cms.ui.assetlist.add_locale=Add data for language
cms.ui.assetlist.name=Name
cms.ui.assetlist.title=Title
cms.ui.assetlist.description=Description

View File

@ -34,7 +34,7 @@ import com.arsdigita.bebop.table.TableModelBuilder;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.util.LockableImpl;
import org.libreccm.admin.ui.UsersGroupsRoles;
import org.libreccm.admin.ui.UsersGroupsRolesTab;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.security.Group;
import org.libreccm.security.Party;

View File

@ -23,18 +23,11 @@ import com.arsdigita.ui.admin.AdminUiConstants;
import com.vaadin.cdi.CDIView;
import com.vaadin.navigator.View;
import com.vaadin.navigator.ViewChangeListener;
import com.vaadin.server.ClassResource;
import com.vaadin.server.VaadinServlet;
import com.vaadin.shared.ui.MarginInfo;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.CssLayout;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.Image;
import com.vaadin.ui.Label;
import com.vaadin.ui.TabSheet;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.themes.ValoTheme;
import org.apache.shiro.subject.Subject;
import org.libreccm.l10n.GlobalizationHelper;
import org.libreccm.security.GroupManager;
@ -107,7 +100,7 @@ public class AdminView extends CustomComponent implements View {
private final TabSheet tabSheet;
// private final Grid<User> usersTable;
private final TabSheet.Tab tabUsersGroupsRoles;
private final UsersGroupsRoles usersGroupsRoles;
private final UsersGroupsRolesTab usersGroupsRoles;
private final JpqlConsole jpqlConsole;
@ -115,7 +108,7 @@ public class AdminView extends CustomComponent implements View {
tabSheet = new TabSheet();
usersGroupsRoles = new UsersGroupsRoles(this);
usersGroupsRoles = new UsersGroupsRolesTab(this);
tabUsersGroupsRoles = tabSheet.addTab(usersGroupsRoles,
"Users/Groups/Roles");

View File

@ -0,0 +1,38 @@
/*
* 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;
import com.vaadin.ui.CustomComponent;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class ConfigurationTab extends CustomComponent {
private static final long serialVersionUID = 7642627611731762410L;
public ConfigurationTab(final AdminView adminView) {
}
}

View File

@ -0,0 +1,32 @@
/*
* 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;
import com.vaadin.cdi.ViewScoped;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@ViewScoped
public class ConfigurationsTabController {
}

View File

@ -0,0 +1,112 @@
/*
* 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;
import com.vaadin.cdi.ViewScoped;
import com.vaadin.data.provider.AbstractDataProvider;
import com.vaadin.data.provider.Query;
import org.libreccm.configuration.ConfigurationInfo;
import org.libreccm.configuration.ConfigurationManager;
import org.libreccm.l10n.GlobalizationHelper;
import java.util.SortedSet;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.inject.Inject;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@ViewScoped
public class ConfigurationsTableDataProvider extends AbstractDataProvider<Class<?>, String> {
private static final long serialVersionUID = -7001151229931864885L;
private String filter;
@Inject
private ConfigurationManager confManager;
@Inject
private GlobalizationHelper globalizationHelper;
@Override
public boolean isInMemory() {
return false;
}
@Override
public int size(final Query<Class<?>, String> query) {
if (filter == null || filter.trim().isEmpty()) {
return confManager.findAllConfigurations().size();
} else {
return (int) confManager
.findAllConfigurations()
.stream()
.filter(conf -> {
final ConfigurationInfo info = confManager
.getConfigurationInfo(conf);
// return c.getName().startsWith(filterTerm);
if (filter == null || filter.isEmpty()) {
return true;
} else {
return info
.getTitle(globalizationHelper.getNegotiatedLocale())
.startsWith(
filter);
}
})
.count();
}
}
@Override
public Stream<Class<?>> fetch(final Query<Class<?>, String> query) {
if (filter == null || filter.trim().isEmpty()) {
return confManager.findAllConfigurations().stream();
} else {
return confManager
.findAllConfigurations()
.stream()
.filter(conf -> {
final ConfigurationInfo info = confManager
.getConfigurationInfo(conf);
// return c.getName().startsWith(filterTerm);
if (filter == null || filter.isEmpty()) {
return true;
} else {
return info
.getTitle(globalizationHelper.getNegotiatedLocale())
.startsWith(
filter);
}
})
.collect(Collectors.toList())
.subList(query.getOffset(), query.getOffset() + query.getLimit())
.stream();
}
}
public void setFilter(final String filter) {
this.filter = filter;
}
}

View File

@ -68,7 +68,7 @@ public class GroupDetails extends Window {
private static final String COL_ROLE_NAME = "role_name";
private static final String COL_ROLE_REMOVE = "remove";
private final UsersGroupsRoles usersGroupsRoles;
private final UsersGroupsRolesTab usersGroupsRoles;
private final Group group;
private final GroupRepository groupRepo;
@ -80,7 +80,7 @@ public class GroupDetails extends Window {
private HorizontalLayout saveCancelButtons;
public GroupDetails(final Group group,
final UsersGroupsRoles usersGroupsRoles,
final UsersGroupsRolesTab usersGroupsRoles,
final GroupRepository groupRepo) {
super(String.format("Edit group %s", group.getName()));

View File

@ -47,7 +47,7 @@ public class GroupEditor extends Window {
private static final long serialVersionUID = -5834095844674226692L;
private final UsersGroupsRoles usersGroupsRoles;
private final UsersGroupsRolesTab usersGroupsRoles;
private final Group group;
private final GroupRepository groupRepo;
private final GroupManager groupManager;
@ -56,7 +56,7 @@ public class GroupEditor extends Window {
private TextField groupName;
public GroupEditor(final UsersGroupsRoles usersGroupsRoles,
public GroupEditor(final UsersGroupsRolesTab usersGroupsRoles,
final GroupRepository groupRepo,
final GroupManager groupManager) {
@ -71,7 +71,7 @@ public class GroupEditor extends Window {
}
public GroupEditor(final Group group,
final UsersGroupsRoles usersGroupsRoles,
final UsersGroupsRolesTab usersGroupsRoles,
final GroupRepository groupRepo,
final GroupManager groupManager) {

View File

@ -43,7 +43,7 @@ public class GroupSelector extends Window {
public GroupSelector(final String caption,
final String actionLabel,
final UsersGroupsRoles usersGroupsRoles,
final UsersGroupsRolesTab usersGroupsRoles,
final List<Group> excludedGroups,
final GroupSelectionAction action) {

View File

@ -57,7 +57,7 @@ public class GroupsTable extends Grid<Group> {
private final Button createGroupButton;
public GroupsTable(final AdminView view,
final UsersGroupsRoles usersGroupsRoles) {
final UsersGroupsRolesTab usersGroupsRoles) {
super();
@ -158,11 +158,11 @@ public class GroupsTable extends Grid<Group> {
private static final long serialVersionUID = -1168912882249598278L;
private final Group group;
private final UsersGroupsRoles usersGroupsRoles;
private final UsersGroupsRolesTab usersGroupsRoles;
private final GroupRepository groupRepo;
public ConfirmDeleteDialog(final Group group,
final UsersGroupsRoles usersGroupsRoles,
final UsersGroupsRolesTab usersGroupsRoles,
final GroupRepository groupRepo) {
this.group = group;

View File

@ -47,7 +47,7 @@ public class PartySelector extends Window {
public PartySelector(final String caption,
final String actionLabel,
final UsersGroupsRoles usersGroupsRoles,
final UsersGroupsRolesTab usersGroupsRoles,
final List<Party> excludedParties,
final PartySelectionAction action) {

View File

@ -54,13 +54,13 @@ public class RoleDetails extends Window {
private static final String COL_MEMBER_NAME = "partyname";
private static final String COL_MEMBER_REMOVE = "member_remove";
private final UsersGroupsRoles usersGroupsRoles;
private final UsersGroupsRolesTab usersGroupsRoles;
private final Role role;
private final RoleRepository roleRepo;
private final RoleManager roleManager;
public RoleDetails(final Role role,
final UsersGroupsRoles usersGroupsRoles,
final UsersGroupsRolesTab usersGroupsRoles,
final RoleRepository roleRepo,
final RoleManager roleManager) {

View File

@ -45,7 +45,7 @@ public class RoleEditor extends Window {
private static final long serialVersionUID = -2982855646090602847L;
private final UsersGroupsRoles usersGroupsRoles;
private final UsersGroupsRolesTab usersGroupsRoles;
private final Role role;
private final RoleRepository roleRepo;
private final RoleManager roleManager;
@ -55,7 +55,7 @@ public class RoleEditor extends Window {
private TextField roleName;
private TextArea roleDescription;
public RoleEditor(final UsersGroupsRoles usersGroupsRoles,
public RoleEditor(final UsersGroupsRolesTab usersGroupsRoles,
final RoleRepository roleRepo,
final RoleManager roleManager) {
@ -70,7 +70,7 @@ public class RoleEditor extends Window {
}
public RoleEditor(final Role role,
final UsersGroupsRoles usersGroupsRoles,
final UsersGroupsRolesTab usersGroupsRoles,
final RoleRepository roleRepo,
final RoleManager roleManager) {

View File

@ -44,7 +44,7 @@ public class RoleSelector extends Window {
public RoleSelector(final String caption,
final String actionLabel,
final UsersGroupsRoles usersGroupsRoles,
final UsersGroupsRolesTab usersGroupsRoles,
final List<Role> excludedRoles,
final RoleSelectionAction action) {

View File

@ -60,7 +60,7 @@ public class RolesTable extends Grid<Role> {
private final Button createRoleButton;
public RolesTable(final AdminView view,
final UsersGroupsRoles usersGroupsRoles) {
final UsersGroupsRolesTab usersGroupsRoles) {
super();
@ -194,11 +194,11 @@ public class RolesTable extends Grid<Role> {
private static final long serialVersionUID = -1315311220464298282L;
private final Role role;
private final UsersGroupsRoles usersGroupsRoles;
private final UsersGroupsRolesTab usersGroupsRoles;
private final RoleRepository roleRepo;
public ConfirmDeleteDialog(final Role role,
final UsersGroupsRoles usersGroupsRoles,
final UsersGroupsRolesTab usersGroupsRoles,
final RoleRepository roleRepo) {
this.role = role;
this.usersGroupsRoles = usersGroupsRoles;

View File

@ -59,13 +59,13 @@ public class UserDetails extends Window {
private static final String COL_ROLE_NAME = "role_name";
private static final String COL_ROLE_REMOVE = "role_remove";
private final UsersGroupsRoles usersGroupsRoles;
private final UsersGroupsRolesTab usersGroupsRoles;
private final User user;
private final UserRepository userRepo;
private final UserManager userManager;
public UserDetails(final User user,
final UsersGroupsRoles usersGroupsRoles,
final UsersGroupsRolesTab usersGroupsRoles,
final UserRepository userRepo,
final UserManager userManager) {

View File

@ -71,7 +71,7 @@ public class UserEditor extends Window {
}
private final UsersGroupsRoles usersGroupsRoles;
private final UsersGroupsRolesTab usersGroupsRoles;
private final User user;
private final UserRepository userRepo;
private final UserManager userManager;
@ -88,7 +88,7 @@ public class UserEditor extends Window {
private CheckBox passwordResetRequired;
private CheckBox banned;
public UserEditor(final UsersGroupsRoles usersGroupsRoles,
public UserEditor(final UsersGroupsRolesTab usersGroupsRoles,
final UserRepository userRepo,
final UserManager userManager) {
@ -103,7 +103,7 @@ public class UserEditor extends Window {
}
public UserEditor(final User user,
final UsersGroupsRoles usersGroupsRoles,
final UsersGroupsRolesTab usersGroupsRoles,
final UserRepository userRepo,
final UserManager userManager) {

View File

@ -51,7 +51,7 @@ public class UserSelector extends Window {
public UserSelector(final String caption,
final String actionLabel,
final UsersGroupsRoles usersGroupsRoles,
final UsersGroupsRolesTab usersGroupsRoles,
final List<User> excludedUsers,
final UserSelectionAction action) {

View File

@ -23,8 +23,6 @@ import com.arsdigita.ui.admin.AdminUiConstants;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.TabSheet;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import org.libreccm.admin.ui.AdminView;
import java.util.ResourceBundle;
@ -32,7 +30,7 @@ import java.util.ResourceBundle;
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class UsersGroupsRoles extends CustomComponent {
public class UsersGroupsRolesTab extends CustomComponent {
private static final long serialVersionUID = 7280416743018127366L;
@ -63,7 +61,7 @@ public class UsersGroupsRoles extends CustomComponent {
private GroupsTableDataProvider groupsTableDataProvider;
private RolesTableDataProvider rolesTableDataProvider;
public UsersGroupsRoles(final AdminView view) {
public UsersGroupsRolesTab(final AdminView view) {
this.view = view;
@ -179,7 +177,7 @@ public class UsersGroupsRoles extends CustomComponent {
tabSheet.addTab(groupsTable, "Groups");
tabSheet.addTab(rolesTable, "Roles");
setCompositionRoot(tabSheet);
super.setCompositionRoot(tabSheet);
}

View File

@ -57,7 +57,7 @@ public class UsersTable extends Grid<User> {
private final Button createUserButton;
public UsersTable(final AdminView view,
final UsersGroupsRoles usersGroupsRoles) {
final UsersGroupsRolesTab usersGroupsRoles) {
super();