CCM NG/ccm-cms: AssetForm including localisation for assets
git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4663 8810af33-2d31-482b-a856-94f89814c4df
Former-commit-id: ee7280dc6b
pull/2/head
parent
65c0776a67
commit
2ece488abb
|
|
@ -18,18 +18,27 @@
|
||||||
*/
|
*/
|
||||||
package com.arsdigita.cms.ui.assets;
|
package com.arsdigita.cms.ui.assets;
|
||||||
|
|
||||||
|
import com.arsdigita.bebop.BoxPanel;
|
||||||
import com.arsdigita.bebop.ColumnPanel;
|
import com.arsdigita.bebop.ColumnPanel;
|
||||||
import com.arsdigita.bebop.Form;
|
import com.arsdigita.bebop.Form;
|
||||||
import com.arsdigita.bebop.FormProcessException;
|
import com.arsdigita.bebop.FormProcessException;
|
||||||
import com.arsdigita.bebop.Label;
|
import com.arsdigita.bebop.Label;
|
||||||
|
import com.arsdigita.bebop.Page;
|
||||||
import com.arsdigita.bebop.PageState;
|
import com.arsdigita.bebop.PageState;
|
||||||
import com.arsdigita.bebop.SaveCancelSection;
|
import com.arsdigita.bebop.SaveCancelSection;
|
||||||
import com.arsdigita.bebop.SingleSelectionModel;
|
import com.arsdigita.bebop.SingleSelectionModel;
|
||||||
|
import com.arsdigita.bebop.Text;
|
||||||
import com.arsdigita.bebop.event.FormInitListener;
|
import com.arsdigita.bebop.event.FormInitListener;
|
||||||
import com.arsdigita.bebop.event.FormProcessListener;
|
import com.arsdigita.bebop.event.FormProcessListener;
|
||||||
import com.arsdigita.bebop.event.FormSectionEvent;
|
import com.arsdigita.bebop.event.FormSectionEvent;
|
||||||
import com.arsdigita.bebop.event.FormSubmissionListener;
|
import com.arsdigita.bebop.event.FormSubmissionListener;
|
||||||
|
import com.arsdigita.bebop.event.PrintEvent;
|
||||||
|
import com.arsdigita.bebop.event.PrintListener;
|
||||||
|
import com.arsdigita.bebop.form.Option;
|
||||||
|
import com.arsdigita.bebop.form.SingleSelect;
|
||||||
|
import com.arsdigita.bebop.form.Submit;
|
||||||
import com.arsdigita.bebop.form.TextField;
|
import com.arsdigita.bebop.form.TextField;
|
||||||
|
import com.arsdigita.bebop.parameters.StringParameter;
|
||||||
import com.arsdigita.globalization.GlobalizedMessage;
|
import com.arsdigita.globalization.GlobalizedMessage;
|
||||||
import com.arsdigita.kernel.KernelConfig;
|
import com.arsdigita.kernel.KernelConfig;
|
||||||
|
|
||||||
|
|
@ -39,9 +48,16 @@ import org.librecms.contentsection.Asset;
|
||||||
import org.librecms.contentsection.AssetRepository;
|
import org.librecms.contentsection.AssetRepository;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.libreccm.categorization.CategoryManager;
|
import org.libreccm.categorization.CategoryManager;
|
||||||
|
import org.libreccm.core.UnexpectedErrorException;
|
||||||
|
import org.librecms.assets.AssetL10NManager;
|
||||||
import org.librecms.contentsection.Folder;
|
import org.librecms.contentsection.Folder;
|
||||||
import org.librecms.contentsection.FolderManager;
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.TooManyListenersException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -55,6 +71,15 @@ public abstract class AssetForm extends Form implements FormInitListener,
|
||||||
|
|
||||||
private final AssetPane assetPane;
|
private final AssetPane assetPane;
|
||||||
private final SingleSelectionModel<Long> selectionModel;
|
private final SingleSelectionModel<Long> selectionModel;
|
||||||
|
// private final StringParameter selectedLocaleParameter;
|
||||||
|
|
||||||
|
private BoxPanel showLocalePanel;
|
||||||
|
private SingleSelect showLocaleSelect;
|
||||||
|
private Submit showLocaleSubmit;
|
||||||
|
|
||||||
|
private BoxPanel addLocalePanel;
|
||||||
|
private SingleSelect addLocaleSelect;
|
||||||
|
private Submit addLocaleSubmit;
|
||||||
|
|
||||||
private TextField title;
|
private TextField title;
|
||||||
private SaveCancelSection saveCancelSection;
|
private SaveCancelSection saveCancelSection;
|
||||||
|
|
@ -64,11 +89,146 @@ public abstract class AssetForm extends Form implements FormInitListener,
|
||||||
|
|
||||||
this.assetPane = assetPane;
|
this.assetPane = assetPane;
|
||||||
selectionModel = assetPane.getSelectedAssetModel();
|
selectionModel = assetPane.getSelectedAssetModel();
|
||||||
|
// selectedLocaleParameter = new StringParameter("selected-locale");
|
||||||
|
|
||||||
initComponents();
|
initComponents();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
|
|
||||||
|
showLocalePanel = new BoxPanel(BoxPanel.HORIZONTAL);
|
||||||
|
final Label showLocaleLabel = new Label(new PrintListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void prepare(final PrintEvent event) {
|
||||||
|
final PageState state = event.getPageState();
|
||||||
|
final Optional<Asset> selectedAsset = getSelectedAsset(state);
|
||||||
|
final Label target = (Label) event.getTarget();
|
||||||
|
if (selectedAsset.isPresent()) {
|
||||||
|
target.setLabel(new GlobalizedMessage(
|
||||||
|
"cms.ui.assest.show_locale",
|
||||||
|
CmsConstants.CMS_BUNDLE));
|
||||||
|
} else {
|
||||||
|
target.setLabel(new GlobalizedMessage(
|
||||||
|
"cms.ui.assest.initial_locale",
|
||||||
|
CmsConstants.CMS_BUNDLE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
showLocaleSelect = new SingleSelect("selected-locale");
|
||||||
|
try {
|
||||||
|
showLocaleSelect.addPrintListener(new PrintListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void prepare(final PrintEvent event) {
|
||||||
|
final PageState state = event.getPageState();
|
||||||
|
|
||||||
|
final Optional<Asset> selectedAsset
|
||||||
|
= getSelectedAsset(state);
|
||||||
|
if (selectedAsset.isPresent()) {
|
||||||
|
final SingleSelect target = (SingleSelect) event
|
||||||
|
.getTarget();
|
||||||
|
|
||||||
|
target.clearOptions();;
|
||||||
|
|
||||||
|
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||||
|
final AssetL10NManager l10nManager = cdiUtil
|
||||||
|
.findBean(AssetL10NManager.class);
|
||||||
|
final List<Locale> availableLocales = new ArrayList<>(
|
||||||
|
l10nManager.availableLocales(selectedAsset.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.asset.show_locale",
|
||||||
|
CmsConstants.CMS_BUNDLE));
|
||||||
|
showLocalePanel.add(showLocaleLabel);
|
||||||
|
showLocalePanel.add(showLocaleSelect);
|
||||||
|
showLocalePanel.add(showLocaleSubmit);
|
||||||
|
add(showLocalePanel);
|
||||||
|
|
||||||
|
addLocalePanel = new BoxPanel(BoxPanel.HORIZONTAL) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isVisible(final PageState state) {
|
||||||
|
return getSelectedAsset(state).isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
final Label addLocaleLabel = new Label(
|
||||||
|
new GlobalizedMessage("cms.ui.assest.add_locale",
|
||||||
|
CmsConstants.CMS_BUNDLE));
|
||||||
|
addLocaleSelect = new SingleSelect("add-locale-select");
|
||||||
|
try {
|
||||||
|
addLocaleSelect.addPrintListener(new PrintListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void prepare(final PrintEvent event) {
|
||||||
|
final PageState state = event.getPageState();
|
||||||
|
|
||||||
|
final Optional<Asset> selectedAsset
|
||||||
|
= getSelectedAsset(state);
|
||||||
|
if (selectedAsset.isPresent()) {
|
||||||
|
final SingleSelect target = (SingleSelect) event
|
||||||
|
.getTarget();
|
||||||
|
|
||||||
|
target.clearOptions();
|
||||||
|
|
||||||
|
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||||
|
final AssetL10NManager l10nManager = cdiUtil
|
||||||
|
.findBean(AssetL10NManager.class);
|
||||||
|
final List<Locale> creatableLocales = new ArrayList<>(
|
||||||
|
l10nManager.creatableLocales(selectedAsset.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.asset.add_locale",
|
||||||
|
CmsConstants.CMS_BUNDLE));
|
||||||
|
addLocalePanel.add(addLocaleLabel);
|
||||||
|
addLocalePanel.add(addLocaleSelect);
|
||||||
|
addLocalePanel.add(addLocaleSubmit);
|
||||||
|
add(addLocalePanel);
|
||||||
|
|
||||||
add(new Label(new GlobalizedMessage("cms.ui.asset.title",
|
add(new Label(new GlobalizedMessage("cms.ui.asset.title",
|
||||||
CmsConstants.CMS_BUNDLE)));
|
CmsConstants.CMS_BUNDLE)));
|
||||||
title = new TextField(ASSET_TITLE);
|
title = new TextField(ASSET_TITLE);
|
||||||
|
|
@ -88,6 +248,15 @@ public abstract class AssetForm extends Form implements FormInitListener,
|
||||||
//Nothing here
|
//Nothing here
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
// public void register(final Page page) {
|
||||||
|
// super.register(page);
|
||||||
|
//
|
||||||
|
// page.addComponentStateParam(this, selectedLocaleParameter);
|
||||||
|
//
|
||||||
|
// page.setVisibleDefault(showLocalePanel, true);
|
||||||
|
// page.setVisibleDefault(addLocalePanel, true);
|
||||||
|
// }
|
||||||
protected String getTitle(final PageState state) {
|
protected String getTitle(final PageState state) {
|
||||||
return (String) title.getValue(state);
|
return (String) title.getValue(state);
|
||||||
}
|
}
|
||||||
|
|
@ -99,13 +268,13 @@ public abstract class AssetForm extends Form implements FormInitListener,
|
||||||
} else {
|
} else {
|
||||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||||
final AssetRepository assetRepo = cdiUtil.findBean(
|
final AssetRepository assetRepo = cdiUtil.findBean(
|
||||||
AssetRepository.class);
|
AssetRepository.class);
|
||||||
final Asset asset = assetRepo
|
final Asset asset = assetRepo
|
||||||
.findById(selectionModel.getSelectedKey(state))
|
.findById(selectionModel.getSelectedKey(state))
|
||||||
.orElseThrow(() -> new IllegalArgumentException(String.
|
.orElseThrow(() -> new IllegalArgumentException(String.
|
||||||
format(
|
format(
|
||||||
"No asset with ID %d in the database.",
|
"No asset with ID %d in the database.",
|
||||||
selectionModel.getSelectedKey(state))));
|
selectionModel.getSelectedKey(state))));
|
||||||
return Optional.of(asset);
|
return Optional.of(asset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -118,23 +287,78 @@ public abstract class AssetForm extends Form implements FormInitListener,
|
||||||
final Optional<Asset> selectedAsset = getSelectedAsset(state);
|
final Optional<Asset> selectedAsset = getSelectedAsset(state);
|
||||||
|
|
||||||
if (selectedAsset.isPresent()) {
|
if (selectedAsset.isPresent()) {
|
||||||
|
// showLocalePanel.setVisible(state, true);
|
||||||
|
// addLocalePanel.setVisible(state, true);
|
||||||
|
|
||||||
|
showLocaleSelect.setValue(state,
|
||||||
|
KernelConfig
|
||||||
|
.getConfig()
|
||||||
|
.getDefaultLocale()
|
||||||
|
.toString());
|
||||||
|
|
||||||
title.setValue(state,
|
title.setValue(state,
|
||||||
selectedAsset
|
selectedAsset
|
||||||
.get()
|
.get()
|
||||||
.getTitle()
|
.getTitle()
|
||||||
.getValue(KernelConfig
|
.getValue(getSelectedLocale(state)));
|
||||||
.getConfig()
|
} else {
|
||||||
.getDefaultLocale()));
|
showLocaleSelect.setValue(state,
|
||||||
|
KernelConfig
|
||||||
|
.getConfig()
|
||||||
|
.getDefaultLocale()
|
||||||
|
.toString());
|
||||||
|
// showLocalePanel.setVisible(state, false);
|
||||||
|
// addLocalePanel.setVisible(state, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initForm(state, selectedAsset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void initForm(final PageState state,
|
||||||
|
final Optional<Asset> selectedAsset);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(final FormSectionEvent event)
|
public void process(final FormSectionEvent event)
|
||||||
throws FormProcessException {
|
throws FormProcessException {
|
||||||
|
|
||||||
final PageState state = event.getPageState();
|
final PageState state = event.getPageState();
|
||||||
|
|
||||||
|
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||||
|
|
||||||
|
if (showLocaleSubmit.isSelected(state)) {
|
||||||
|
|
||||||
|
final Optional<Asset> selectedAsset = getSelectedAsset(state);
|
||||||
|
|
||||||
|
if (selectedAsset.isPresent()) {
|
||||||
|
|
||||||
|
title.setValue(state,
|
||||||
|
selectedAsset
|
||||||
|
.get()
|
||||||
|
.getTitle()
|
||||||
|
.getValue(getSelectedLocale(state)));
|
||||||
|
showLocale(state);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addLocaleSubmit.isSelected(state)) {
|
||||||
|
final AssetL10NManager l10nManager = cdiUtil
|
||||||
|
.findBean(AssetL10NManager.class);
|
||||||
|
final Locale add = new Locale((String) addLocaleSelect
|
||||||
|
.getValue(state));
|
||||||
|
final Optional<Asset> selectedAsset = getSelectedAsset(state);
|
||||||
|
l10nManager.addLanguage(selectedAsset.get(), add);
|
||||||
|
}
|
||||||
|
|
||||||
if (saveCancelSection.getSaveButton().isSelected(state)) {
|
if (saveCancelSection.getSaveButton().isSelected(state)) {
|
||||||
final Optional<Asset> selectedAsset = getSelectedAsset(state);
|
final Optional<Asset> selectedAsset = getSelectedAsset(state);
|
||||||
final Asset asset;
|
final Asset asset;
|
||||||
|
|
@ -145,46 +369,46 @@ public abstract class AssetForm extends Form implements FormInitListener,
|
||||||
asset = createAsset(state);
|
asset = createAsset(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
asset.getTitle().addValue(
|
asset.getTitle().addValue(getSelectedLocale(state),
|
||||||
KernelConfig.getConfig().getDefaultLocale(),
|
(String) title.getValue(state));
|
||||||
(String) title.getValue(state));
|
|
||||||
|
|
||||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
|
||||||
final AssetRepository assetRepo = cdiUtil
|
final AssetRepository assetRepo = cdiUtil
|
||||||
.findBean(AssetRepository.class);
|
.findBean(AssetRepository.class);
|
||||||
assetRepo.save(asset);
|
assetRepo.save(asset);
|
||||||
|
|
||||||
if (!selectedAsset.isPresent()) {
|
if (!selectedAsset.isPresent()) {
|
||||||
//Set display name
|
//Set display name
|
||||||
asset.setDisplayName((String) title.getValue(state));
|
asset.setDisplayName((String) title.getValue(state));
|
||||||
assetRepo.save(asset);
|
assetRepo.save(asset);
|
||||||
|
|
||||||
//Add new asset to currently selected folder
|
//Add new asset to currently selected folder
|
||||||
final Folder selectedFolder = assetPane
|
final Folder selectedFolder = assetPane
|
||||||
.getFolderSelectionModel()
|
.getFolderSelectionModel()
|
||||||
.getSelectedObject(state);
|
.getSelectedObject(state);
|
||||||
final CategoryManager categoryManager = cdiUtil
|
final CategoryManager categoryManager = cdiUtil
|
||||||
.findBean(CategoryManager.class);
|
.findBean(CategoryManager.class);
|
||||||
categoryManager.addObjectToCategory(
|
categoryManager.addObjectToCategory(
|
||||||
asset,
|
asset,
|
||||||
selectedFolder,
|
selectedFolder,
|
||||||
CmsConstants.CATEGORIZATION_TYPE_FOLDER);
|
CmsConstants.CATEGORIZATION_TYPE_FOLDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
assetPane.browseMode(state);
|
assetPane.browseMode(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract void showLocale(final PageState state);
|
||||||
|
|
||||||
protected abstract Asset createAsset(final PageState state)
|
protected abstract Asset createAsset(final PageState state)
|
||||||
throws FormProcessException;
|
throws FormProcessException;
|
||||||
|
|
||||||
protected abstract void updateAsset(final Asset asset,
|
protected abstract void updateAsset(final Asset asset,
|
||||||
final PageState state)
|
final PageState state)
|
||||||
throws FormProcessException;
|
throws FormProcessException;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void submitted(final FormSectionEvent event)
|
public void submitted(final FormSectionEvent event)
|
||||||
throws FormProcessException {
|
throws FormProcessException {
|
||||||
|
|
||||||
final PageState state = event.getPageState();
|
final PageState state = event.getPageState();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -501,7 +501,7 @@ public class AssetPane extends LayoutPanel implements Resettable {
|
||||||
|
|
||||||
actionsSegment.add(newAssetForm);
|
actionsSegment.add(newAssetForm);
|
||||||
|
|
||||||
final MetaForm editAssetForm = new MetaForm(MOVE) {
|
final MetaForm editAssetForm = new MetaForm("editAsset") {
|
||||||
@Override
|
@Override
|
||||||
public Form buildForm(final PageState state) {
|
public Form buildForm(final PageState state) {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ import org.librecms.contentsection.Asset;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -56,8 +57,8 @@ public class BookmarkForm extends AssetForm {
|
||||||
protected void addWidgets() {
|
protected void addWidgets() {
|
||||||
|
|
||||||
add(new Label(
|
add(new Label(
|
||||||
new GlobalizedMessage("cms.ui.assets.bookmark.description",
|
new GlobalizedMessage("cms.ui.assets.bookmark.description",
|
||||||
CmsConstants.CMS_BUNDLE)));
|
CmsConstants.CMS_BUNDLE)));
|
||||||
description = new TextArea("bookmark-description");
|
description = new TextArea("bookmark-description");
|
||||||
add(description);
|
add(description);
|
||||||
|
|
||||||
|
|
@ -70,7 +71,7 @@ public class BookmarkForm extends AssetForm {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void validate(final FormSectionEvent event)
|
public void validate(final FormSectionEvent event)
|
||||||
throws FormProcessException {
|
throws FormProcessException {
|
||||||
|
|
||||||
final PageState state = event.getPageState();
|
final PageState state = event.getPageState();
|
||||||
final FormData data = event.getFormData();
|
final FormData data = event.getFormData();
|
||||||
|
|
@ -79,8 +80,8 @@ public class BookmarkForm extends AssetForm {
|
||||||
new URL((String) url.getValue(state));
|
new URL((String) url.getValue(state));
|
||||||
} catch (MalformedURLException ex) {
|
} catch (MalformedURLException ex) {
|
||||||
data.addError(new GlobalizedMessage(
|
data.addError(new GlobalizedMessage(
|
||||||
"cms.ui.assets.bookmark.url.malformed",
|
"cms.ui.assets.bookmark.url.malformed",
|
||||||
CmsConstants.CMS_BUNDLE));
|
CmsConstants.CMS_BUNDLE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,18 +89,63 @@ public class BookmarkForm extends AssetForm {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initForm(final PageState state,
|
||||||
|
final Optional<Asset> selectedAsset) {
|
||||||
|
|
||||||
|
if (selectedAsset.isPresent()) {
|
||||||
|
|
||||||
|
if (!(selectedAsset.get() instanceof Bookmark)) {
|
||||||
|
throw new IllegalArgumentException(String.format(
|
||||||
|
"The provided asset must be an instanceof of class '%s' or "
|
||||||
|
+ "an subclass but is an instanceof of class '%s'.",
|
||||||
|
Bookmark.class.getName(),
|
||||||
|
selectedAsset.get().getClass().getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
final Bookmark bookmark = (Bookmark) selectedAsset.get();
|
||||||
|
|
||||||
|
description.setValue(state,
|
||||||
|
bookmark
|
||||||
|
.getDescription()
|
||||||
|
.getValue(getSelectedLocale(state)));
|
||||||
|
url.setValue(state, bookmark.getUrl());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void showLocale(final PageState state) {
|
||||||
|
final Optional<Asset> selectedAsset = getSelectedAsset(state);
|
||||||
|
|
||||||
|
if (selectedAsset.isPresent()) {
|
||||||
|
if (!(getSelectedAsset(state).get() instanceof Bookmark)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Selected asset is not a bookmark");
|
||||||
|
}
|
||||||
|
|
||||||
|
final Bookmark bookmark = (Bookmark) selectedAsset.get();
|
||||||
|
|
||||||
|
description.setValue(state,
|
||||||
|
bookmark
|
||||||
|
.getDescription()
|
||||||
|
.getValue(getSelectedLocale(state)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Asset createAsset(final PageState state)
|
protected Asset createAsset(final PageState state)
|
||||||
throws FormProcessException {
|
throws FormProcessException {
|
||||||
|
|
||||||
Objects.requireNonNull(state);
|
Objects.requireNonNull(state);
|
||||||
|
|
||||||
final Bookmark bookmark = new Bookmark();
|
final Bookmark bookmark = new Bookmark();
|
||||||
|
|
||||||
bookmark
|
bookmark
|
||||||
.getDescription()
|
.getDescription()
|
||||||
.addValue(KernelConfig.getConfig().getDefaultLocale(),
|
.addValue(getSelectedLocale(state),
|
||||||
(String) description.getValue(state));
|
(String) description.getValue(state));
|
||||||
|
|
||||||
bookmark.setUrl((String) url.getValue(state));
|
bookmark.setUrl((String) url.getValue(state));
|
||||||
|
|
||||||
|
|
@ -108,25 +154,25 @@ public class BookmarkForm extends AssetForm {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateAsset(final Asset asset, final PageState state)
|
protected void updateAsset(final Asset asset, final PageState state)
|
||||||
throws FormProcessException {
|
throws FormProcessException {
|
||||||
|
|
||||||
Objects.requireNonNull(asset);
|
Objects.requireNonNull(asset);
|
||||||
Objects.requireNonNull(state);
|
Objects.requireNonNull(state);
|
||||||
|
|
||||||
if (!(asset instanceof Bookmark)) {
|
if (!(asset instanceof Bookmark)) {
|
||||||
throw new IllegalArgumentException(String.format(
|
throw new IllegalArgumentException(String.format(
|
||||||
"Provided asset is not an instance of class (or sub class of) "
|
"Provided asset is not an instance of class (or sub class of) "
|
||||||
+ "'%s' but is an instance of class '%s'",
|
+ "'%s' but is an instance of class '%s'",
|
||||||
Bookmark.class.getName(),
|
Bookmark.class.getName(),
|
||||||
asset.getClass().getName()));
|
asset.getClass().getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
final Bookmark bookmark = (Bookmark) asset;
|
final Bookmark bookmark = (Bookmark) asset;
|
||||||
|
|
||||||
bookmark
|
bookmark
|
||||||
.getDescription()
|
.getDescription()
|
||||||
.addValue(KernelConfig.getConfig().getDefaultLocale(),
|
.addValue(getSelectedLocale(state),
|
||||||
(String) description.getValue(state));
|
(String) description.getValue(state));
|
||||||
|
|
||||||
bookmark.setUrl((String) url.getValue(state));
|
bookmark.setUrl((String) url.getValue(state));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,10 +29,13 @@ import com.arsdigita.globalization.GlobalizedMessage;
|
||||||
import com.arsdigita.kernel.KernelConfig;
|
import com.arsdigita.kernel.KernelConfig;
|
||||||
|
|
||||||
import org.librecms.CmsConstants;
|
import org.librecms.CmsConstants;
|
||||||
|
import org.librecms.assets.Bookmark;
|
||||||
import org.librecms.assets.LegalMetadata;
|
import org.librecms.assets.LegalMetadata;
|
||||||
import org.librecms.contentsection.Asset;
|
import org.librecms.contentsection.Asset;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -53,42 +56,87 @@ public class LegalMetadataForm extends AssetForm {
|
||||||
protected void addWidgets() {
|
protected void addWidgets() {
|
||||||
|
|
||||||
add(new Label(new GlobalizedMessage(
|
add(new Label(new GlobalizedMessage(
|
||||||
"cms.ui.assets.legalmetadata.rightsholder",
|
"cms.ui.assets.legalmetadata.rightsholder",
|
||||||
CmsConstants.CMS_BUNDLE)));
|
CmsConstants.CMS_BUNDLE)));
|
||||||
rightsHolder = new TextArea("legalmetadata-rightsholder");
|
rightsHolder = new TextArea("legalmetadata-rightsholder");
|
||||||
add(rightsHolder);
|
add(rightsHolder);
|
||||||
|
|
||||||
add(new Label(new GlobalizedMessage(
|
add(new Label(new GlobalizedMessage(
|
||||||
"cms.ui.assets.legalmetadata.rights",
|
"cms.ui.assets.legalmetadata.rights",
|
||||||
CmsConstants.CMS_BUNDLE)));
|
CmsConstants.CMS_BUNDLE)));
|
||||||
rights = new TextArea("legalmetadata-rights");
|
rights = new TextArea("legalmetadata-rights");
|
||||||
add(rights);
|
add(rights);
|
||||||
|
|
||||||
add(new Label(new GlobalizedMessage(
|
add(new Label(new GlobalizedMessage(
|
||||||
"cms.ui.assets.legalmetadata.publisher",
|
"cms.ui.assets.legalmetadata.publisher",
|
||||||
CmsConstants.CMS_BUNDLE)));
|
CmsConstants.CMS_BUNDLE)));
|
||||||
publisher = new TextArea("legalmetadata-rights");
|
publisher = new TextArea("legalmetadata-rights");
|
||||||
add(publisher);
|
add(publisher);
|
||||||
|
|
||||||
add(new Label(new GlobalizedMessage(
|
add(new Label(new GlobalizedMessage(
|
||||||
"cms.ui.assets.legalmetadata.creator",
|
"cms.ui.assets.legalmetadata.creator",
|
||||||
CmsConstants.CMS_BUNDLE)));
|
CmsConstants.CMS_BUNDLE)));
|
||||||
creator = new TextArea("legalmetadata-creator");
|
creator = new TextArea("legalmetadata-creator");
|
||||||
add(creator);
|
add(creator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initForm(final PageState state,
|
||||||
|
final Optional<Asset> selectedAsset) {
|
||||||
|
|
||||||
|
if (selectedAsset.isPresent()) {
|
||||||
|
|
||||||
|
if (!(selectedAsset.get() instanceof LegalMetadata)) {
|
||||||
|
throw new IllegalArgumentException(String.format(
|
||||||
|
"The provided asset must be an instanceof of class '%s' or "
|
||||||
|
+ "an subclass but is an instanceof of class '%s'.",
|
||||||
|
LegalMetadata.class.getName(),
|
||||||
|
selectedAsset.get().getClass().getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
final LegalMetadata legalMetadata = (LegalMetadata) selectedAsset
|
||||||
|
.get();
|
||||||
|
|
||||||
|
rightsHolder.setValue(state, legalMetadata.getRightsHolder());
|
||||||
|
rights.setValue(state,
|
||||||
|
legalMetadata
|
||||||
|
.getRights()
|
||||||
|
.getValue(getSelectedLocale(state)));
|
||||||
|
publisher.setValue(state, legalMetadata.getPublisher());
|
||||||
|
creator.setValue(state, legalMetadata.getCreator());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void showLocale(final PageState state) {
|
||||||
|
final Optional<Asset> selectedAsset = getSelectedAsset(state);
|
||||||
|
|
||||||
|
if (selectedAsset.isPresent()) {
|
||||||
|
if (!(getSelectedAsset(state).get() instanceof LegalMetadata)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Selected asset is not a legal metadata");
|
||||||
|
}
|
||||||
|
|
||||||
|
final LegalMetadata legalMetadata = (LegalMetadata) selectedAsset.get();
|
||||||
|
|
||||||
|
rights.setValue(state,
|
||||||
|
legalMetadata
|
||||||
|
.getRights()
|
||||||
|
.getValue(getSelectedLocale(state)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Asset createAsset(final PageState state)
|
protected Asset createAsset(final PageState state)
|
||||||
throws FormProcessException {
|
throws FormProcessException {
|
||||||
|
|
||||||
Objects.requireNonNull(state);
|
Objects.requireNonNull(state);
|
||||||
|
|
||||||
final LegalMetadata legalMetadata = new LegalMetadata();
|
final LegalMetadata legalMetadata = new LegalMetadata();
|
||||||
|
|
||||||
legalMetadata.setRightsHolder((String) rightsHolder.getValue(state));
|
legalMetadata.setRightsHolder((String) rightsHolder.getValue(state));
|
||||||
legalMetadata.getRights().addValue(
|
legalMetadata.getRights().addValue(getSelectedLocale(state),
|
||||||
KernelConfig.getConfig().getDefaultLocale(),
|
(String) rights.getValue(state));
|
||||||
(String) rights.getValue(state));
|
|
||||||
|
|
||||||
legalMetadata.setPublisher((String) publisher.getValue(state));
|
legalMetadata.setPublisher((String) publisher.getValue(state));
|
||||||
legalMetadata.setCreator((String) creator.getValue(state));
|
legalMetadata.setCreator((String) creator.getValue(state));
|
||||||
|
|
@ -98,25 +146,25 @@ public class LegalMetadataForm extends AssetForm {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateAsset(final Asset asset, final PageState state)
|
protected void updateAsset(final Asset asset, final PageState state)
|
||||||
throws FormProcessException {
|
throws FormProcessException {
|
||||||
|
|
||||||
Objects.requireNonNull(asset);
|
Objects.requireNonNull(asset);
|
||||||
Objects.requireNonNull(state);
|
Objects.requireNonNull(state);
|
||||||
|
|
||||||
if (!(asset instanceof LegalMetadata)) {
|
if (!(asset instanceof LegalMetadata)) {
|
||||||
throw new IllegalArgumentException(String.format(
|
throw new IllegalArgumentException(String.format(
|
||||||
"Provided asset is not an instance of '%s' (or a sub class) "
|
"Provided asset is not an instance of '%s' (or a sub class) "
|
||||||
+ "but is an instance of class '%s'.",
|
+ "but is an instance of class '%s'.",
|
||||||
LegalMetadata.class.getName(),
|
LegalMetadata.class
|
||||||
asset.getClass().getName()));
|
.getName(),
|
||||||
|
asset.getClass().getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
final LegalMetadata legalMetadata = (LegalMetadata) asset;
|
final LegalMetadata legalMetadata = (LegalMetadata) asset;
|
||||||
|
|
||||||
legalMetadata.setRightsHolder((String) rightsHolder.getValue(state));
|
legalMetadata.setRightsHolder((String) rightsHolder.getValue(state));
|
||||||
legalMetadata.getRights().addValue(
|
legalMetadata.getRights().addValue(getSelectedLocale(state),
|
||||||
KernelConfig.getConfig().getDefaultLocale(),
|
(String) rights.getValue(state));
|
||||||
(String) rights.getValue(state));
|
|
||||||
|
|
||||||
legalMetadata.setPublisher((String) publisher.getValue(state));
|
legalMetadata.setPublisher((String) publisher.getValue(state));
|
||||||
legalMetadata.setCreator((String) creator.getValue(state));
|
legalMetadata.setCreator((String) creator.getValue(state));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,344 @@
|
||||||
|
/*
|
||||||
|
* 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.assets;
|
||||||
|
|
||||||
|
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.PermissionChecker;
|
||||||
|
import org.libreccm.security.RequiresPrivilege;
|
||||||
|
import org.librecms.contentsection.Asset;
|
||||||
|
import org.librecms.contentsection.AssetRepository;
|
||||||
|
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.transaction.Transactional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages the language versions of an asset.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@RequestScoped
|
||||||
|
public class AssetL10NManager {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ConfigurationManager confManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private AssetRepository assetRepo;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private PermissionChecker permissionChecker;
|
||||||
|
|
||||||
|
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 Asset asset) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
final PropertyDescriptor[] properties = Introspector
|
||||||
|
.getBeanInfo(asset.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 Asset asset,
|
||||||
|
final Method readMethod) {
|
||||||
|
try {
|
||||||
|
return (LocalizedString) readMethod.invoke(asset);
|
||||||
|
} catch (IllegalAccessException
|
||||||
|
| IllegalArgumentException
|
||||||
|
| InvocationTargetException ex) {
|
||||||
|
throw new UnexpectedErrorException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<Locale> collectLanguages(final Asset asset) {
|
||||||
|
|
||||||
|
final Set<Locale> locales = new HashSet<>();
|
||||||
|
|
||||||
|
findLocalizedStringProperties(asset)
|
||||||
|
.stream()
|
||||||
|
.map(property -> property.getReadMethod())
|
||||||
|
.map(readMethod -> readLocalizedString(asset, readMethod))
|
||||||
|
.forEach(str -> locales.addAll(str.getAvailableLocales()));
|
||||||
|
|
||||||
|
return locales;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method for reading methods in this class for verifying that the
|
||||||
|
* current user is permitted to read the item.
|
||||||
|
*
|
||||||
|
* @param asset The asset for which the read permission is verified
|
||||||
|
*/
|
||||||
|
private void checkReadPermission(final Asset asset) {
|
||||||
|
|
||||||
|
final String requiredPrivilege = AssetPrivileges.VIEW;
|
||||||
|
|
||||||
|
permissionChecker.checkPermission(requiredPrivilege, asset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves all languages in which an asset is available.
|
||||||
|
*
|
||||||
|
* @param asset The asset.
|
||||||
|
*
|
||||||
|
* @return An (unmodifiable) {@link Set} containing all languages in which
|
||||||
|
* the asset is available.
|
||||||
|
*/
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public Set<Locale> availableLocales(final Asset asset) {
|
||||||
|
|
||||||
|
checkReadPermission(asset);
|
||||||
|
return Collections.unmodifiableSet(collectLanguages(asset));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if an asset has data for particular language.
|
||||||
|
*
|
||||||
|
* @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}
|
||||||
|
* if not.
|
||||||
|
*/
|
||||||
|
@AuthorizationRequired
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public boolean hasLanguage(
|
||||||
|
@RequiresPrivilege(AssetPrivileges.VIEW)
|
||||||
|
final Asset asset,
|
||||||
|
final Locale locale) {
|
||||||
|
|
||||||
|
Objects.requireNonNull(asset,
|
||||||
|
"Can't check if asset null has a specific locale.");
|
||||||
|
Objects.requireNonNull(locale, "Can't check for locale null.");
|
||||||
|
|
||||||
|
checkReadPermission(asset);
|
||||||
|
|
||||||
|
return collectLanguages(asset).contains(locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a {@link Set} containing the locales for which the asset does not
|
||||||
|
* yet have a variant.
|
||||||
|
*
|
||||||
|
* @param asset The asset.
|
||||||
|
*
|
||||||
|
* @return A {@link Set} with the locales for which the item does not have a
|
||||||
|
* variant.
|
||||||
|
*/
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public Set<Locale> creatableLocales(final Asset asset) {
|
||||||
|
checkReadPermission(asset);
|
||||||
|
|
||||||
|
return supportedLocales.stream()
|
||||||
|
.filter(locale -> !hasLanguage(asset, locale))
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a language to an asset. The method will retrieve all fields of the
|
||||||
|
* type {@link LocalizedString} from the asset 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 asset The asset 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 Asset asset,
|
||||||
|
final Locale locale) {
|
||||||
|
|
||||||
|
Objects.requireNonNull(asset, "Can't add language to asset null.");
|
||||||
|
Objects.requireNonNull(asset, "Cant't add language null to an asset.");
|
||||||
|
|
||||||
|
findLocalizedStringProperties(asset)
|
||||||
|
.forEach(property -> addLanguage(asset, locale, property));
|
||||||
|
|
||||||
|
assetRepo.save(asset);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addLanguage(final Asset asset,
|
||||||
|
final Locale locale,
|
||||||
|
final PropertyDescriptor property) {
|
||||||
|
|
||||||
|
final Method readMethod = property.getReadMethod();
|
||||||
|
final LocalizedString localizedStr = readLocalizedString(asset,
|
||||||
|
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 asset. This method will retrieve all
|
||||||
|
* fields of the type {@link LocalizedString} from the asset and remove the
|
||||||
|
* entry for the provided locale if the field has an entry for that locale.
|
||||||
|
*
|
||||||
|
* @param asset
|
||||||
|
* @param locale
|
||||||
|
*/
|
||||||
|
@AuthorizationRequired
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public void removeLanguage(
|
||||||
|
@RequiresPrivilege(AssetPrivileges.EDIT)
|
||||||
|
final Asset asset,
|
||||||
|
final Locale locale) {
|
||||||
|
|
||||||
|
Objects.requireNonNull(asset, "Can't remove language to asset null.");
|
||||||
|
Objects
|
||||||
|
.requireNonNull(asset, "Cant't remove language null to an asset.");
|
||||||
|
|
||||||
|
findLocalizedStringProperties(asset)
|
||||||
|
.forEach(property -> removeLanguage(asset, locale, property));
|
||||||
|
|
||||||
|
assetRepo.save(asset);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeLanguage(final Asset asset,
|
||||||
|
final Locale locale,
|
||||||
|
final PropertyDescriptor property) {
|
||||||
|
|
||||||
|
final Method readMethod = property.getReadMethod();
|
||||||
|
|
||||||
|
final LocalizedString localizedStr = readLocalizedString(asset,
|
||||||
|
readMethod);
|
||||||
|
if (localizedStr.hasValue(locale)) {
|
||||||
|
localizedStr.removeValue(locale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method normalises the values of the fields of type
|
||||||
|
* {@link LocalizedString} of an asset. The method will first retrieve all
|
||||||
|
* fields of the type {@link LocalizedString} from the asset 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 asset The asset to normalise.
|
||||||
|
*/
|
||||||
|
@AuthorizationRequired
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public void normalizeLanguages(
|
||||||
|
@RequiresPrivilege(AssetPrivileges.EDIT)
|
||||||
|
final Asset asset) {
|
||||||
|
|
||||||
|
Objects.requireNonNull(asset, "Can't normalise asset null");
|
||||||
|
|
||||||
|
final Set<Locale> languages = collectLanguages(asset);
|
||||||
|
|
||||||
|
findLocalizedStringProperties(asset)
|
||||||
|
.stream()
|
||||||
|
.map(property -> property.getReadMethod())
|
||||||
|
.map(readMethod -> readLocalizedString(asset, 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -83,11 +83,16 @@ public class ContentItemL10NManager {
|
||||||
final ContentItem item) {
|
final ContentItem item) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return Arrays.stream(
|
final PropertyDescriptor[] properties = Introspector
|
||||||
Introspector.getBeanInfo(item.getClass())
|
.getBeanInfo(item.getClass())
|
||||||
.getPropertyDescriptors())
|
.getPropertyDescriptors();
|
||||||
.filter(property -> property.getPropertyType().isAssignableFrom(
|
|
||||||
LocalizedString.class))
|
return Arrays.stream(properties)
|
||||||
|
.filter(property -> {
|
||||||
|
return property
|
||||||
|
.getPropertyType()
|
||||||
|
.isAssignableFrom(LocalizedString.class);
|
||||||
|
})
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
} catch (IntrospectionException ex) {
|
} catch (IntrospectionException ex) {
|
||||||
throw new UnexpectedErrorException(ex);
|
throw new UnexpectedErrorException(ex);
|
||||||
|
|
@ -106,6 +111,7 @@ public class ContentItemL10NManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<Locale> collectLanguages(final ContentItem item) {
|
private Set<Locale> collectLanguages(final ContentItem item) {
|
||||||
|
|
||||||
final Set<Locale> locales = new HashSet<>();
|
final Set<Locale> locales = new HashSet<>();
|
||||||
|
|
||||||
findLocalizedStringProperties(item)
|
findLocalizedStringProperties(item)
|
||||||
|
|
@ -146,7 +152,7 @@ public class ContentItemL10NManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves all languages in which content item is available.
|
* Retrieves all languages in which a content item is available.
|
||||||
*
|
*
|
||||||
* @param item The item.
|
* @param item The item.
|
||||||
*
|
*
|
||||||
|
|
@ -154,8 +160,7 @@ public class ContentItemL10NManager {
|
||||||
* the item is available.
|
* the item is available.
|
||||||
*/
|
*/
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public Set<Locale> availableLanguages(
|
public Set<Locale> availableLanguages(final ContentItem item) {
|
||||||
final ContentItem item) {
|
|
||||||
|
|
||||||
checkReadPermission(item);
|
checkReadPermission(item);
|
||||||
return Collections.unmodifiableSet(collectLanguages(item));
|
return Collections.unmodifiableSet(collectLanguages(item));
|
||||||
|
|
@ -205,7 +210,7 @@ public class ContentItemL10NManager {
|
||||||
checkReadPermission(item);
|
checkReadPermission(item);
|
||||||
|
|
||||||
return supportedLocales.stream()
|
return supportedLocales.stream()
|
||||||
.filter(locale -> hasLanguage(item, locale))
|
.filter(locale -> !hasLanguage(item, locale))
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -329,7 +334,7 @@ public class ContentItemL10NManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
findLocalizedStringProperties(item)
|
findLocalizedStringProperties(item)
|
||||||
.forEach(property -> ContentItemL10NManager.this.removeLanguage(item, locale, property));
|
.forEach(property -> removeLanguage(item, locale, property));
|
||||||
|
|
||||||
itemRepo.save(item);
|
itemRepo.save(item);
|
||||||
}
|
}
|
||||||
|
|
@ -357,13 +362,13 @@ public class ContentItemL10NManager {
|
||||||
* not an entry for the language is added.
|
* not an entry for the language is added.
|
||||||
*
|
*
|
||||||
* @param item The item to normalise. The item <strong>must be</strong> the
|
* @param item The item to normalise. The item <strong>must be</strong> the
|
||||||
* <strong>draft version</strong> of the item! If a <em>live
|
* <strong>draft version</strong> of the item! If a <em>live version</em> or
|
||||||
* version</em> or a <em>pending version</em> is provided the
|
* a <em>pending version</em> is provided the method will throw an
|
||||||
* method will throw an {@link IllegalArgumentException}!
|
* {@link IllegalArgumentException}!
|
||||||
*/
|
*/
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public void normalizedLanguages(
|
public void normalizeLanguages(
|
||||||
@RequiresPrivilege(ItemPrivileges.EDIT)
|
@RequiresPrivilege(ItemPrivileges.EDIT)
|
||||||
final ContentItem item) {
|
final ContentItem item) {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -392,7 +392,7 @@ public class ContentItemL10NManagerTest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to normalise the languages of a content item by using
|
* Tries to normalise the languages of a content item by using
|
||||||
* {@link ContentItemL10NManager#normalizedLanguages(org.librecms.contentsection.ContentItem)}
|
* {@link ContentItemL10NManager#normalizeLanguages(org.librecms.contentsection.ContentItem)}
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@InSequence(120)
|
@InSequence(120)
|
||||||
|
|
@ -406,12 +406,12 @@ public class ContentItemL10NManagerTest {
|
||||||
final Optional<ContentItem> item = itemRepo.findById(-10200L);
|
final Optional<ContentItem> item = itemRepo.findById(-10200L);
|
||||||
assertThat(item.isPresent(), is(true));
|
assertThat(item.isPresent(), is(true));
|
||||||
|
|
||||||
l10nManager.normalizedLanguages(item.get());
|
l10nManager.normalizeLanguages(item.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies that calling
|
* Verifies that calling
|
||||||
* {@link ContentItemL10NManager#normalizedLanguages(org.librecms.contentsection.ContentItem)}
|
* {@link ContentItemL10NManager#normalizeLanguages(org.librecms.contentsection.ContentItem)}
|
||||||
* for already normalised item has not effect.
|
* for already normalised item has not effect.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -425,13 +425,13 @@ public class ContentItemL10NManagerTest {
|
||||||
final Optional<ContentItem> item = itemRepo.findById(-10100L);
|
final Optional<ContentItem> item = itemRepo.findById(-10100L);
|
||||||
assertThat(item.isPresent(), is(true));
|
assertThat(item.isPresent(), is(true));
|
||||||
|
|
||||||
l10nManager.normalizedLanguages(item.get());
|
l10nManager.normalizeLanguages(item.get());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies that
|
* Verifies that
|
||||||
* {@link ContentItemL10NManager#normalizedLanguages(org.librecms.contentsection.ContentItem)}
|
* {@link ContentItemL10NManager#normalizeLanguages(org.librecms.contentsection.ContentItem)}
|
||||||
* throws an {@link IllegalArgumentException} if called with {@code null}
|
* throws an {@link IllegalArgumentException} if called with {@code null}
|
||||||
* for the item.
|
* for the item.
|
||||||
*/
|
*/
|
||||||
|
|
@ -446,7 +446,7 @@ public class ContentItemL10NManagerTest {
|
||||||
public void normalizeItemNull() {
|
public void normalizeItemNull() {
|
||||||
final ContentItem item = null;
|
final ContentItem item = null;
|
||||||
|
|
||||||
l10nManager.normalizedLanguages(item);
|
l10nManager.normalizeLanguages(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue