Removed depcreated package com/arsdigita/cms/ui/assets from ccm-cms
parent
4bb0117366
commit
6bfa90616b
|
|
@ -35,7 +35,6 @@ import org.librecms.contentsection.ContentItem;
|
|||
import org.librecms.contentsection.ContentSection;
|
||||
|
||||
import com.arsdigita.cms.dispatcher.CMSPage;
|
||||
import com.arsdigita.cms.ui.assets.AssetPane;
|
||||
import com.arsdigita.cms.ui.category.CategoryAdminPane;
|
||||
//ToDo NG import com.arsdigita.cms.ui.category.CategoryAdminPane;
|
||||
import com.arsdigita.cms.ui.cse.ContentSoonExpiredPane;
|
||||
|
|
@ -123,7 +122,7 @@ public class ContentSectionPage extends CMSPage implements ActionListener {
|
|||
private FolderAdminPane m_folderPane;
|
||||
private BrowsePane m_browsePane;
|
||||
private ItemSearch m_searchPane;
|
||||
private AssetPane m_assetPane;
|
||||
// private AssetPane m_assetPane;
|
||||
//ToDo NG private ImagesPane m_imagesPane;
|
||||
private RoleAdminPane m_rolePane;
|
||||
private WorkflowAdminPane m_workflowPane;
|
||||
|
|
@ -261,13 +260,13 @@ public class ContentSectionPage extends CMSPage implements ActionListener {
|
|||
return m_searchPane;
|
||||
}
|
||||
|
||||
protected AssetPane getAssetPane() {
|
||||
if (m_assetPane == null) {
|
||||
m_assetPane = new AssetPane();
|
||||
}
|
||||
|
||||
return m_assetPane;
|
||||
}
|
||||
// protected AssetPane getAssetPane() {
|
||||
// if (m_assetPane == null) {
|
||||
// m_assetPane = new AssetPane();
|
||||
// }
|
||||
//
|
||||
// return m_assetPane;
|
||||
// }
|
||||
|
||||
// ToDo NG
|
||||
// protected ImagesPane getImagesPane() {
|
||||
|
|
|
|||
|
|
@ -1,433 +0,0 @@
|
|||
/*
|
||||
* 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.assets;
|
||||
|
||||
import com.arsdigita.bebop.BoxPanel;
|
||||
import com.arsdigita.bebop.ColumnPanel;
|
||||
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.SingleSelectionModel;
|
||||
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.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.globalization.GlobalizedMessage;
|
||||
import com.arsdigita.kernel.KernelConfig;
|
||||
|
||||
import org.libreccm.cdi.utils.CdiUtil;
|
||||
import org.librecms.CmsConstants;
|
||||
import org.librecms.contentsection.Asset;
|
||||
|
||||
import org.libreccm.core.UnexpectedErrorException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.TooManyListenersException;
|
||||
|
||||
/**
|
||||
* Basic Form for manipulating assets.
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
* @param <T> The type of the asset.
|
||||
*/
|
||||
public abstract class AbstractAssetForm<T extends Asset>
|
||||
extends Form implements FormInitListener,
|
||||
FormProcessListener,
|
||||
FormSubmissionListener {
|
||||
|
||||
private static final String ASSET_TITLE = "asset-name";
|
||||
|
||||
private static final String ASSET_NAME = "asset-title";
|
||||
|
||||
private final AssetPane assetPane;
|
||||
|
||||
private final SingleSelectionModel<Long> selectionModel;
|
||||
|
||||
private BoxPanel showLocalePanel;
|
||||
|
||||
private SingleSelect showLocaleSelect;
|
||||
|
||||
private Submit showLocaleSubmit;
|
||||
|
||||
private BoxPanel addLocalePanel;
|
||||
|
||||
private SingleSelect addLocaleSelect;
|
||||
|
||||
private Submit addLocaleSubmit;
|
||||
|
||||
private TextField name;
|
||||
|
||||
private TextField title;
|
||||
|
||||
private SaveCancelSection saveCancelSection;
|
||||
|
||||
public AbstractAssetForm(final AssetPane assetPane) {
|
||||
super("asset-form", new ColumnPanel(1));
|
||||
|
||||
this.assetPane = assetPane;
|
||||
selectionModel = assetPane.getSelectedAssetModel();
|
||||
|
||||
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 Long selectedAssetId = getSelectedAssetId(state);
|
||||
final Label target = (Label) event.getTarget();
|
||||
if (selectedAssetId == null) {
|
||||
target.setLabel(new GlobalizedMessage(
|
||||
"cms.ui.asset.initial_locale",
|
||||
CmsConstants.CMS_BUNDLE));
|
||||
} else {
|
||||
target.setLabel(new GlobalizedMessage(
|
||||
"cms.ui.asset.show_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 Long selectedAssetId = getSelectedAssetId(state);
|
||||
if (selectedAssetId == null) {
|
||||
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)));
|
||||
});
|
||||
} else {
|
||||
final SingleSelect target = (SingleSelect) event
|
||||
.getTarget();
|
||||
|
||||
target.clearOptions();
|
||||
|
||||
final List<Locale> availableLocales = getController()
|
||||
.availableLocales(selectedAssetId,
|
||||
getAssetClass());
|
||||
availableLocales.sort((locale1, locale2) -> {
|
||||
return locale1.toString().compareTo(locale2
|
||||
.toString());
|
||||
});
|
||||
availableLocales.forEach(locale -> target.addOption(
|
||||
new Option(locale.toString(),
|
||||
new Text(locale.toString()))));
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
} catch (TooManyListenersException ex) {
|
||||
throw new UnexpectedErrorException(ex);
|
||||
}
|
||||
showLocaleSubmit = new Submit(new GlobalizedMessage(
|
||||
"cms.ui.asset.show_locale",
|
||||
CmsConstants.CMS_BUNDLE)) {
|
||||
|
||||
@Override
|
||||
public boolean isVisible(final PageState state) {
|
||||
return getSelectedAssetId(state) != null;
|
||||
}
|
||||
|
||||
};
|
||||
showLocalePanel.add(showLocaleLabel);
|
||||
showLocalePanel.add(showLocaleSelect);
|
||||
showLocalePanel.add(showLocaleSubmit);
|
||||
add(showLocalePanel);
|
||||
|
||||
addLocalePanel = new BoxPanel(BoxPanel.HORIZONTAL) {
|
||||
|
||||
@Override
|
||||
public boolean isVisible(final PageState state) {
|
||||
return getSelectedAssetId(state) != null;
|
||||
}
|
||||
|
||||
};
|
||||
final Label addLocaleLabel = new Label(
|
||||
new GlobalizedMessage("cms.ui.asset.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 Long selectedAssetId = getSelectedAssetId(state);
|
||||
if (selectedAssetId != null) {
|
||||
final SingleSelect target = (SingleSelect) event
|
||||
.getTarget();
|
||||
|
||||
target.clearOptions();
|
||||
|
||||
final List<Locale> creatableLocales = getController()
|
||||
.creatableLocales(selectedAssetId,
|
||||
getAssetClass());
|
||||
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.name",
|
||||
CmsConstants.CMS_BUNDLE)));
|
||||
name = new TextField(ASSET_NAME);
|
||||
add(name);
|
||||
|
||||
add(new Label(new GlobalizedMessage("cms.ui.asset.title",
|
||||
CmsConstants.CMS_BUNDLE)));
|
||||
title = new TextField(ASSET_TITLE);
|
||||
add(title);
|
||||
|
||||
addWidgets();
|
||||
|
||||
saveCancelSection = new SaveCancelSection();
|
||||
add(saveCancelSection);
|
||||
|
||||
addInitListener(this);
|
||||
addProcessListener(this);
|
||||
addSubmissionListener(this);
|
||||
}
|
||||
|
||||
protected void addWidgets() {
|
||||
//Nothing here
|
||||
}
|
||||
|
||||
protected String getTitle(final PageState state) {
|
||||
return (String) title.getValue(state);
|
||||
}
|
||||
|
||||
protected Long getSelectedAssetId(final PageState state) {
|
||||
|
||||
final Object key = selectionModel.getSelectedKey(state);
|
||||
if (key == null) {
|
||||
return null;
|
||||
} else {
|
||||
return (Long) key;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(final FormSectionEvent event) throws FormProcessException {
|
||||
|
||||
final PageState state = event.getPageState();
|
||||
|
||||
final Long selectedAssetId = getSelectedAssetId(state);
|
||||
|
||||
final Map<String, Object> data;
|
||||
if (selectedAssetId == null) {
|
||||
showLocaleSelect.setValue(state,
|
||||
KernelConfig
|
||||
.getConfig()
|
||||
.getDefaultLocale()
|
||||
.toString());
|
||||
|
||||
data = Collections.emptyMap();
|
||||
|
||||
} else {
|
||||
|
||||
showLocaleSelect.setValue(state,
|
||||
getSelectedLocale(state));
|
||||
|
||||
data = getController().getAssetData(selectedAssetId,
|
||||
getAssetClass(),
|
||||
getSelectedLocale(state));
|
||||
|
||||
name.setValue(state,
|
||||
data.get(AbstractAssetFormController.DISPLAY_NAME));
|
||||
title.setValue(state,
|
||||
data.get(AbstractAssetFormController.TITLE));
|
||||
}
|
||||
|
||||
initForm(state, data);
|
||||
}
|
||||
|
||||
protected Locale getSelectedLocale(final PageState state) {
|
||||
|
||||
final Object selected = showLocaleSelect.getValue(state);
|
||||
if (selected == null) {
|
||||
return KernelConfig.getConfig().getDefaultLocale();
|
||||
} else if (selected instanceof Locale) {
|
||||
return (Locale) selected;
|
||||
} else if (selected instanceof String) {
|
||||
return new Locale((String) selected);
|
||||
} else {
|
||||
return new Locale(selected.toString());
|
||||
}
|
||||
}
|
||||
|
||||
protected String getTitleValue(final PageState state) {
|
||||
return (String) title.getValue(state);
|
||||
}
|
||||
|
||||
protected void initForm(final PageState state,
|
||||
final Map<String, Object> data) {
|
||||
|
||||
if (!data.isEmpty()) {
|
||||
|
||||
name.setValue(state,
|
||||
data.get(AbstractAssetFormController.DISPLAY_NAME));
|
||||
|
||||
// final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
// @SuppressWarnings("unchecked")
|
||||
// final AbstractAssetFormController<T> controller = cdiUtil
|
||||
// .findBean(AbstractAssetFormController.class);
|
||||
title.setValue(state,
|
||||
data.get(AbstractAssetFormController.TITLE));
|
||||
showLocale(state);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(final FormSectionEvent event)
|
||||
throws FormProcessException {
|
||||
|
||||
final PageState state = event.getPageState();
|
||||
|
||||
// final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
if (showLocaleSubmit.isSelected(state)) {
|
||||
|
||||
final Long selectedAssetId = getSelectedAssetId(state);
|
||||
|
||||
initForm(state,
|
||||
getController().getAssetData(selectedAssetId,
|
||||
getAssetClass(),
|
||||
getSelectedLocale(state)));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (addLocaleSubmit.isSelected(state)) {
|
||||
final Locale add = new Locale((String) addLocaleSelect
|
||||
.getValue(state));
|
||||
final Long selectedAssetId = getSelectedAssetId(state);
|
||||
getController().addLocale(selectedAssetId, add, getAssetClass());
|
||||
}
|
||||
|
||||
if (saveCancelSection.getSaveButton().isSelected(state)) {
|
||||
|
||||
final Map<String, Object> data = new HashMap<>();
|
||||
data.put(AbstractAssetFormController.DISPLAY_NAME,
|
||||
name.getValue(state));
|
||||
data.put(AbstractAssetFormController.TITLE,
|
||||
title.getValue(state));
|
||||
data.putAll(collectData(event));
|
||||
|
||||
final Long selectedAssetId;
|
||||
if (getSelectedAssetId(state) == null) {
|
||||
|
||||
selectedAssetId = getController()
|
||||
.createAsset(assetPane
|
||||
.getFolderSelectionModel()
|
||||
.getSelectedObject(state),
|
||||
getSelectedLocale(state),
|
||||
getAssetClass(),
|
||||
data);
|
||||
} else {
|
||||
selectedAssetId = getSelectedAssetId(state);
|
||||
}
|
||||
|
||||
getController().updateAsset(selectedAssetId,
|
||||
getSelectedLocale(state),
|
||||
getAssetClass(),
|
||||
data);
|
||||
|
||||
assetPane.browseMode(state);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract Class<T> getAssetClass();
|
||||
|
||||
protected abstract void showLocale(final PageState state);
|
||||
|
||||
protected abstract Map<String, Object> collectData(
|
||||
final FormSectionEvent event)
|
||||
throws FormProcessException;
|
||||
|
||||
@Override
|
||||
public void submitted(final FormSectionEvent event)
|
||||
throws FormProcessException {
|
||||
|
||||
final PageState state = event.getPageState();
|
||||
|
||||
if (saveCancelSection.getCancelButton().isSelected(state)) {
|
||||
selectionModel.clearSelection(state);
|
||||
assetPane.browseMode(state);
|
||||
}
|
||||
}
|
||||
|
||||
protected AssetFormController<T> getController() {
|
||||
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final AssetFormControllers controllers = cdiUtil
|
||||
.findBean(AssetFormControllers.class);
|
||||
|
||||
return controllers.findController(getAssetClass());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,263 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 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.assets;
|
||||
|
||||
import org.librecms.assets.AssetL10NManager;
|
||||
import org.librecms.contentsection.Asset;
|
||||
import org.librecms.contentsection.AssetManager;
|
||||
import org.librecms.contentsection.AssetRepository;
|
||||
import org.librecms.contentsection.Folder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
/**
|
||||
* An base class for implementations of {@link AssetFormController}.
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
* @param <T>
|
||||
*/
|
||||
public abstract class AbstractAssetFormController<T extends Asset> implements
|
||||
AssetFormController<T> {
|
||||
|
||||
protected static final String DISPLAY_NAME = "displayName";
|
||||
protected static final String TITLE = "title";
|
||||
|
||||
@Inject
|
||||
private AssetManager assetManager;
|
||||
|
||||
@Inject
|
||||
private AssetRepository assetRepository;
|
||||
|
||||
@Inject
|
||||
private AssetL10NManager l10nManager;
|
||||
|
||||
/**
|
||||
* Retrieves the basic data of the provided asset. Subclasses should not
|
||||
* overrride this method. Instead they should provided an implementation of
|
||||
* {@link #getAssetData(org.librecms.contentsection.Asset, java.util.Locale)}.
|
||||
*
|
||||
* @param assetType The {@link Asset} from which the data is read.
|
||||
* @param selectedLocale The locale for which the data is read.
|
||||
*
|
||||
* @return A map with the data of the basic properties of the provided
|
||||
* asset.
|
||||
*/
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
public Map<String, Object> getAssetData(final Long assetId,
|
||||
final Class<T> assetType,
|
||||
final Locale selectedLocale) {
|
||||
|
||||
Objects.requireNonNull(assetId, "Can't get data from asset null.");
|
||||
Objects.requireNonNull(selectedLocale,
|
||||
"Can't get data from asset for locale null.");
|
||||
|
||||
final T asset = loadAsset(assetId, assetType);
|
||||
|
||||
final Map<String, Object> data = new HashMap<>();
|
||||
|
||||
data.put(DISPLAY_NAME, asset.getDisplayName());
|
||||
data.put(TITLE, asset.getTitle().getValue(selectedLocale));
|
||||
|
||||
data.putAll(getAssetData(asset, selectedLocale));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
protected abstract Map<String, Object> getAssetData(
|
||||
final T asset, final Locale selectedLocale);
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
public long createAsset(final Folder infolder,
|
||||
final Locale selectedLocale,
|
||||
final Class<T> assetType,
|
||||
final Map<String, Object> data) {
|
||||
|
||||
if (!data.containsKey(DISPLAY_NAME)) {
|
||||
throw new IllegalArgumentException(
|
||||
"data does not contain a value for displayName.");
|
||||
}
|
||||
|
||||
if (!data.containsKey(TITLE)) {
|
||||
throw new IllegalArgumentException(
|
||||
"data does not contain a value for title.");
|
||||
}
|
||||
|
||||
final String name = (String) data.get(DISPLAY_NAME);
|
||||
final String title = (String) data.get(TITLE);
|
||||
|
||||
final T asset = assetManager
|
||||
.createAsset(name,
|
||||
title,
|
||||
selectedLocale,
|
||||
infolder,
|
||||
assetType);
|
||||
|
||||
return asset.getObjectId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the provided asset with the provided data.
|
||||
*
|
||||
* This method is not intended to be overridden, but can't be {@code final}
|
||||
* because of limitations of CDI. To update type specific properties
|
||||
* implement
|
||||
* {@link #updateAssetProperties(org.librecms.contentsection.Asset, java.util.Locale, java.util.Map)}.
|
||||
*
|
||||
* This method calls
|
||||
* {@link AssetRepository#save(org.librecms.contentsection.Asset)} after the
|
||||
* properties are set to save the changes to the database.
|
||||
*
|
||||
* @param assetId The ID of the asset to update.
|
||||
* @param selectedLocale The locale for which the asset is updated.
|
||||
* @param data The data used to update the asset.
|
||||
*/
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
public void updateAsset(final Long assetId,
|
||||
final Locale selectedLocale,
|
||||
final Class<T> assetType,
|
||||
final Map<String, Object> data) {
|
||||
|
||||
Objects.requireNonNull(selectedLocale,
|
||||
"Can't get update asset for locale null.");
|
||||
Objects.requireNonNull(data, "Can't update asset without data.");
|
||||
|
||||
final T asset = loadAsset(assetId, assetType);
|
||||
if (data.containsKey(DISPLAY_NAME)) {
|
||||
asset.setDisplayName((String) data.get(DISPLAY_NAME));
|
||||
}
|
||||
|
||||
if (data.containsKey(TITLE)) {
|
||||
|
||||
final String title = (String) data.get(TITLE);
|
||||
asset.getTitle().putValue(selectedLocale, title);
|
||||
}
|
||||
|
||||
updateAssetProperties(asset, selectedLocale, data);
|
||||
|
||||
assetRepository.save(asset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method to process data for type specific properties.
|
||||
*
|
||||
* This method is called by
|
||||
* {@link #updateAsset(org.librecms.contentsection.Asset, java.util.Locale, java.util.Map)}.
|
||||
* Implementations should <strong>not</strong> call
|
||||
* {@link AssetRepository#save}. Saving the update asset is done by
|
||||
* {@link #updateAsset(org.librecms.contentsection.Asset, java.util.Locale, java.util.Map)}.
|
||||
*
|
||||
* An implementation should not assume that a value for each property is
|
||||
* present in the provided map. Instead the overriding method should check
|
||||
* if a value for a property is available by using
|
||||
* {@link Map#containsKey(java.lang.Object)} first.
|
||||
*
|
||||
* @param asset The asset to update.
|
||||
* @param selectedLocale The locale for which the asset is updated.
|
||||
* @param data The data used to update the asset.
|
||||
*/
|
||||
public abstract void updateAssetProperties(final T asset,
|
||||
final Locale selectedLocale,
|
||||
final Map<String, Object> data);
|
||||
|
||||
/**
|
||||
* Determines for which locales the provided asset has data.
|
||||
*
|
||||
* @param assetId The asset.
|
||||
*
|
||||
* @return A list of all locales for which the asset has data.
|
||||
*/
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
public List<Locale> availableLocales(final Long assetId,
|
||||
final Class<T> assetType) {
|
||||
|
||||
Objects.requireNonNull(
|
||||
assetId,
|
||||
"Can't get available locales for asset with ID null.");
|
||||
|
||||
final T selectedAsset = loadAsset(assetId, assetType);
|
||||
|
||||
return new ArrayList<>(l10nManager.availableLocales(selectedAsset));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines for locales the asset has no data yet.
|
||||
*
|
||||
* @param assetId The asset.
|
||||
*
|
||||
* @return A list of all locales for which the provided asset has no data
|
||||
* yet.
|
||||
*/
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
public List<Locale> creatableLocales(final Long assetId,
|
||||
final Class<T> assetType) {
|
||||
|
||||
Objects.requireNonNull(
|
||||
assetId,
|
||||
"Can't get creatable locales for asset with ID null.");
|
||||
|
||||
final T selectedAsset = loadAsset(assetId, assetType);
|
||||
|
||||
return new ArrayList<>(l10nManager.creatableLocales(selectedAsset));
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
public void addLocale(final Long assetId,
|
||||
final Locale locale,
|
||||
final Class<T> assetType) {
|
||||
|
||||
Objects.requireNonNull(assetId, "Can't add a locale to asset null.");
|
||||
Objects.requireNonNull(locale, "Can't add locale null to an asset.");
|
||||
|
||||
final T selectedAsset = loadAsset(assetId, assetType);
|
||||
|
||||
l10nManager.addLanguage(selectedAsset, locale);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param assetId
|
||||
* @param assetType
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected T loadAsset(final Long assetId, final Class<T> assetType) {
|
||||
|
||||
Objects.requireNonNull(assetId, "null is not a valid assetId");
|
||||
|
||||
return assetRepository
|
||||
.findById(assetId, assetType)
|
||||
.orElseThrow(() -> new IllegalArgumentException(String.format(
|
||||
"No asset with ID %d found.", assetId)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,446 +0,0 @@
|
|||
/*
|
||||
* 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.assets;
|
||||
|
||||
import com.arsdigita.bebop.Component;
|
||||
import com.arsdigita.bebop.ControlLink;
|
||||
import com.arsdigita.bebop.Image;
|
||||
import com.arsdigita.bebop.Label;
|
||||
import com.arsdigita.bebop.Page;
|
||||
import com.arsdigita.bebop.PageState;
|
||||
import com.arsdigita.bebop.Paginator;
|
||||
import com.arsdigita.bebop.SimpleContainer;
|
||||
import com.arsdigita.bebop.SingleSelectionModel;
|
||||
import com.arsdigita.bebop.Table;
|
||||
import com.arsdigita.bebop.Text;
|
||||
import com.arsdigita.bebop.event.TableActionAdapter;
|
||||
import com.arsdigita.bebop.event.TableActionEvent;
|
||||
import com.arsdigita.bebop.event.TableActionListener;
|
||||
import com.arsdigita.bebop.parameters.StringParameter;
|
||||
import com.arsdigita.bebop.table.DefaultTableCellRenderer;
|
||||
import com.arsdigita.bebop.table.DefaultTableColumnModel;
|
||||
import com.arsdigita.bebop.table.TableCellRenderer;
|
||||
import com.arsdigita.bebop.table.TableColumn;
|
||||
import com.arsdigita.bebop.table.TableHeader;
|
||||
import com.arsdigita.cms.CMS;
|
||||
import com.arsdigita.cms.ui.folder.FolderSelectionModel;
|
||||
import com.arsdigita.globalization.GlobalizedMessage;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.libreccm.cdi.utils.CdiUtil;
|
||||
|
||||
import org.librecms.CmsConstants;
|
||||
import org.librecms.contentsection.ContentSection;
|
||||
import org.librecms.contentsection.ContentSectionManager;
|
||||
|
||||
import static org.librecms.CmsConstants.*;
|
||||
|
||||
/**
|
||||
* Browse folder and assets.
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class AssetFolderBrowser extends Table {
|
||||
|
||||
protected static final String SORT_ACTION_UP = "sortActionUp";
|
||||
protected static final String SORT_ACTION_DOWN = "sortActionDown";
|
||||
protected final static String SORT_KEY_NAME = "name";
|
||||
protected final static String SORT_KEY_TITLE = "title";
|
||||
protected final static String SORT_KEY_TYPE = "type";
|
||||
protected final static String SORT_KEY_LAST_MODIFIED_DATE = "lastModified";
|
||||
protected final static String SORT_KEY_CREATION_DATE = "creationDate";
|
||||
|
||||
private final AssetPane assetPane;
|
||||
private TableActionListener folderChanger;
|
||||
private TableActionListener folderDeleter;
|
||||
private TableColumn nameColumn;
|
||||
private TableColumn deleteColumn;
|
||||
private final StringParameter sortTypeParameter = new StringParameter(
|
||||
"sortType");
|
||||
private final StringParameter sortDirectionParameter = new StringParameter(
|
||||
"sortDir");
|
||||
|
||||
private Paginator paginator;
|
||||
private long folderSize;
|
||||
|
||||
public AssetFolderBrowser(final AssetPane assetPane) {
|
||||
super();
|
||||
sortTypeParameter.setDefaultValue(SORT_KEY_NAME);
|
||||
sortDirectionParameter.setDefaultValue(SORT_ACTION_UP);
|
||||
|
||||
this.assetPane = assetPane;
|
||||
|
||||
initComponents();
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
|
||||
final GlobalizedMessage[] headers = {
|
||||
new GlobalizedMessage("cms.ui.folder.name",
|
||||
CMS_FOLDER_BUNDLE),
|
||||
new GlobalizedMessage("cms.ui.folder.title",
|
||||
CMS_FOLDER_BUNDLE),
|
||||
new GlobalizedMessage("cms.ui.folder.type",
|
||||
CMS_FOLDER_BUNDLE),
|
||||
new GlobalizedMessage("cms.ui.asset.thumbnail",
|
||||
CMS_BUNDLE),
|
||||
new GlobalizedMessage("cms.ui.folder.creation_date",
|
||||
CMS_FOLDER_BUNDLE),
|
||||
new GlobalizedMessage("cms.ui.folder.last_modified",
|
||||
CMS_FOLDER_BUNDLE),
|
||||
new GlobalizedMessage("cms.ui.folder.action",
|
||||
CMS_FOLDER_BUNDLE)};
|
||||
|
||||
setModelBuilder(new AssetFolderBrowserTableModelBuilder());
|
||||
setColumnModel(new DefaultTableColumnModel(headers));
|
||||
setHeader(new TableHeader(getColumnModel()));
|
||||
setClassAttr("dataTable");
|
||||
|
||||
getHeader().setDefaultRenderer(
|
||||
new com.arsdigita.cms.ui.util.DefaultTableCellRenderer());
|
||||
|
||||
nameColumn = getColumn(AssetFolderBrowserTableModel.COL_NAME);
|
||||
nameColumn.setCellRenderer(new NameCellRenderer());
|
||||
nameColumn.setHeaderRenderer(new HeaderCellRenderer(SORT_KEY_NAME));
|
||||
|
||||
getColumn(AssetFolderBrowserTableModel.COL_THUMBNAIL)
|
||||
.setCellRenderer(new ThumbnailCellRenderer());
|
||||
|
||||
getColumn(AssetFolderBrowserTableModel.COL_CREATION_DATE)
|
||||
.setHeaderRenderer(
|
||||
new HeaderCellRenderer(SORT_KEY_CREATION_DATE));
|
||||
getColumn(AssetFolderBrowserTableModel.COL_CREATION_DATE)
|
||||
.setCellRenderer(new DateCellRenderer());
|
||||
|
||||
getColumn(AssetFolderBrowserTableModel.COL_LAST_MODIFIED)
|
||||
.setHeaderRenderer(new HeaderCellRenderer(
|
||||
SORT_KEY_LAST_MODIFIED_DATE));
|
||||
getColumn(AssetFolderBrowserTableModel.COL_LAST_MODIFIED)
|
||||
.setCellRenderer(new DateCellRenderer());
|
||||
|
||||
deleteColumn = getColumn(AssetFolderBrowserTableModel.COL_DELETEABLE);
|
||||
deleteColumn.setCellRenderer(new ActionCellRenderer());
|
||||
deleteColumn.setAlign("center");
|
||||
|
||||
folderChanger = new FolderChanger();
|
||||
addTableActionListener(folderChanger);
|
||||
|
||||
folderDeleter = new ItemDeleter();
|
||||
addTableActionListener(folderDeleter);
|
||||
|
||||
setEmptyView(new Label(new GlobalizedMessage("cms.ui.folder.no_assets",
|
||||
CMS_FOLDER_BUNDLE)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(final Page page) {
|
||||
|
||||
super.register(page);
|
||||
|
||||
page.addComponentStateParam(
|
||||
this,
|
||||
getFolderSelectionModel().getStateParameter());
|
||||
page.addComponentStateParam(this, sortTypeParameter);
|
||||
page.addComponentStateParam(this, sortDirectionParameter);
|
||||
}
|
||||
|
||||
protected FolderSelectionModel getFolderSelectionModel() {
|
||||
return assetPane.getFolderSelectionModel();
|
||||
}
|
||||
|
||||
protected SingleSelectionModel<Long> getSelectedAssetModel() {
|
||||
return assetPane.getSelectedAssetModel();
|
||||
}
|
||||
|
||||
protected Paginator getPaginator() {
|
||||
return paginator;
|
||||
}
|
||||
|
||||
protected void setPaginator(final Paginator paginator) {
|
||||
this.paginator = paginator;
|
||||
}
|
||||
|
||||
protected String getSortType(final PageState state) {
|
||||
return (String) state.getValue(sortTypeParameter);
|
||||
}
|
||||
|
||||
protected String getSortDirection(final PageState state) {
|
||||
return (String) state.getValue(sortDirectionParameter);
|
||||
}
|
||||
|
||||
private class HeaderCellRenderer extends DefaultTableCellRenderer {
|
||||
|
||||
private final String headerKey;
|
||||
|
||||
public HeaderCellRenderer(final String headerKey) {
|
||||
super(true);
|
||||
this.headerKey = headerKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getComponent(final Table table,
|
||||
final PageState state,
|
||||
final Object value,
|
||||
final boolean isSelected,
|
||||
final Object key,
|
||||
final int row,
|
||||
final int column) {
|
||||
|
||||
final GlobalizedMessage headerName = (GlobalizedMessage) value;
|
||||
final String sortKey = (String) state.getValue(sortTypeParameter);
|
||||
final boolean isCurrentKey = sortKey.equals(key);
|
||||
final String currentSortDirection = (String) state
|
||||
.getValue(sortDirectionParameter);
|
||||
final String imageUrlStub;
|
||||
|
||||
if (SORT_ACTION_UP.equals(currentSortDirection)) {
|
||||
imageUrlStub = "gray-triangle-up.gif";
|
||||
} else {
|
||||
imageUrlStub = "gray-triangle-down.gif";
|
||||
}
|
||||
|
||||
final ControlLink link = new ControlLink(new Label(headerName)) {
|
||||
|
||||
@Override
|
||||
public void setControlEvent(final PageState state) {
|
||||
String sortDirectionAction;
|
||||
// by default, everything sorts "up" unless it
|
||||
// is the current key and it is already pointing up
|
||||
if (SORT_ACTION_UP.equals(currentSortDirection)
|
||||
&& isCurrentKey) {
|
||||
sortDirectionAction = SORT_ACTION_DOWN;
|
||||
} else {
|
||||
sortDirectionAction = SORT_ACTION_UP;
|
||||
}
|
||||
state.setControlEvent(table,
|
||||
sortDirectionAction,
|
||||
headerKey);
|
||||
}
|
||||
|
||||
};
|
||||
final Label label = new Label();
|
||||
label.setLabel(headerName);
|
||||
label.setClassAttr("folderBrowserLink");
|
||||
label.setOutputEscaping(false);
|
||||
label.setFontWeight(Label.BOLD);
|
||||
|
||||
final SimpleContainer container = new SimpleContainer();
|
||||
container.add(label);
|
||||
if (isCurrentKey) {
|
||||
Image image = new Image("/assets/" + imageUrlStub);
|
||||
image.setBorder("0");
|
||||
container.add(image);
|
||||
}
|
||||
link.setChild(container);
|
||||
return link;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Produce links to view an item or control links for folders to change into
|
||||
* the folder.
|
||||
*/
|
||||
private class NameCellRenderer extends DefaultTableCellRenderer {
|
||||
|
||||
public NameCellRenderer() {
|
||||
super(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getComponent(final Table table,
|
||||
final PageState state,
|
||||
final Object value,
|
||||
final boolean isSelected,
|
||||
final Object key,
|
||||
final int row,
|
||||
final int column) {
|
||||
|
||||
final String name = (String) value;
|
||||
final ContentSection section = CMS.getContext().
|
||||
getContentSection();
|
||||
final ContentSectionManager sectionManager = CdiUtil.
|
||||
createCdiUtil()
|
||||
.findBean(ContentSectionManager.class);
|
||||
|
||||
final boolean isFolder = ((AssetFolderBrowserTableModel) table
|
||||
.getTableModel(state))
|
||||
.isFolder();
|
||||
final long objectId = getObjectId(key);
|
||||
|
||||
if (isFolder) {
|
||||
//return new ControlLink(new Text(name));
|
||||
return super.getComponent(table,
|
||||
state,
|
||||
value,
|
||||
isSelected,
|
||||
objectId,
|
||||
row,
|
||||
column);
|
||||
} else {
|
||||
return new ControlLink(new Text(name));
|
||||
|
||||
// return new Link(new Text(name),
|
||||
// itemResolver.generateItemURL(state,
|
||||
// objectId,
|
||||
// name,
|
||||
// section,
|
||||
// "DRAFT"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class ThumbnailCellRenderer implements TableCellRenderer {
|
||||
|
||||
@Override
|
||||
public Component getComponent(final Table table,
|
||||
final PageState state,
|
||||
final Object value,
|
||||
final boolean isSelected,
|
||||
final Object key,
|
||||
final int row,
|
||||
final int column) {
|
||||
if (value == null) {
|
||||
return new Text("");
|
||||
} else {
|
||||
final Image image = new Image((String) value, "");
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class DateCellRenderer implements TableCellRenderer {
|
||||
|
||||
@Override
|
||||
public Component getComponent(final Table table,
|
||||
final PageState state,
|
||||
final Object value,
|
||||
final boolean isSelected,
|
||||
final Object key,
|
||||
final int row,
|
||||
final int column) {
|
||||
if (value instanceof Date) {
|
||||
final Date date = (Date) value;
|
||||
return new Text(String.format("%1$TF %1$TT", date));
|
||||
} else if (value == null) {
|
||||
return new Text("");
|
||||
} else {
|
||||
return new Text(value.toString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Produce delete links for items and non-empty folders.
|
||||
*/
|
||||
private class ActionCellRenderer implements TableCellRenderer {
|
||||
|
||||
@Override
|
||||
public Component getComponent(final Table table,
|
||||
final PageState state,
|
||||
final Object value,
|
||||
final boolean isSelected,
|
||||
final Object key,
|
||||
final int row,
|
||||
final int column) {
|
||||
if ((!(Boolean) value)) {
|
||||
return new Label(" ", false);
|
||||
} else {
|
||||
final ControlLink link = new ControlLink(
|
||||
new Label(
|
||||
new GlobalizedMessage("cms.ui.folder.delete",
|
||||
CmsConstants.CMS_FOLDER_BUNDLE)));
|
||||
link.setConfirmation(
|
||||
new GlobalizedMessage(
|
||||
"cms.ui.folder.delete_confirmation_assets",
|
||||
CmsConstants.CMS_FOLDER_BUNDLE));
|
||||
return link;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Deletes an item
|
||||
private class ItemDeleter extends TableActionAdapter {
|
||||
|
||||
@Override
|
||||
public void cellSelected(final TableActionEvent event) {
|
||||
int col = event.getColumn();
|
||||
|
||||
if (deleteColumn != getColumn(col)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final PageState state = event.getPageState();
|
||||
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final AssetFolderBrowserController controller = cdiUtil.findBean(
|
||||
AssetFolderBrowserController.class);
|
||||
controller.deleteObject((String) event.getRowKey());
|
||||
|
||||
((Table) event.getSource()).clearSelection(state);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class FolderChanger extends TableActionAdapter {
|
||||
|
||||
@Override
|
||||
public void cellSelected(final TableActionEvent event) {
|
||||
final PageState state = event.getPageState();
|
||||
final int col = event.getColumn();
|
||||
|
||||
if (nameColumn != getColumn(col)) {
|
||||
return;
|
||||
}
|
||||
|
||||
clearSelection(state);
|
||||
final String rowKey = (String) event.getRowKey();
|
||||
if (rowKey.startsWith(CmsConstants.FOLDER_BROWSER_KEY_PREFIX_FOLDER)) {
|
||||
getFolderSelectionModel().setSelectedKey(state,
|
||||
getObjectId(rowKey));
|
||||
} else if (rowKey.startsWith(
|
||||
CmsConstants.FOLDER_BROWSER_KEY_PREFIX_ASSET)) {
|
||||
getSelectedAssetModel().setSelectedKey(state,
|
||||
getObjectId(rowKey));
|
||||
assetPane.editAssetMode(state);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private long getObjectId(final Object key) {
|
||||
|
||||
final String keyStr = (String) key;
|
||||
|
||||
if (keyStr.startsWith("folder-")) {
|
||||
return Long.parseLong(keyStr.substring("folder-".length()));
|
||||
} else if (keyStr.startsWith("asset-")) {
|
||||
return Long.parseLong(keyStr.substring("asset-".length()));
|
||||
} else {
|
||||
return Long.parseLong(keyStr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,638 +0,0 @@
|
|||
/*
|
||||
* 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.assets;
|
||||
|
||||
import com.arsdigita.cms.CMS;
|
||||
import com.arsdigita.kernel.KernelConfig;
|
||||
import com.arsdigita.web.CCMDispatcherServlet;
|
||||
|
||||
import org.libreccm.categorization.Category;
|
||||
import org.libreccm.categorization.CategoryManager;
|
||||
import org.libreccm.configuration.ConfigurationManager;
|
||||
import org.libreccm.l10n.GlobalizationHelper;
|
||||
import org.librecms.CmsConstants;
|
||||
import org.librecms.assets.AssetTypeInfo;
|
||||
import org.librecms.assets.AssetTypesManager;
|
||||
import org.librecms.contentsection.Asset;
|
||||
|
||||
import org.librecms.contentsection.Folder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.TypedQuery;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Join;
|
||||
import javax.persistence.criteria.Order;
|
||||
import javax.persistence.criteria.Path;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
import org.libreccm.core.CcmObject;
|
||||
import org.librecms.contentsection.AssetManager;
|
||||
import org.librecms.contentsection.AssetRepository;
|
||||
import org.librecms.contentsection.FolderManager;
|
||||
import org.librecms.contentsection.FolderRepository;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.librecms.assets.Image;
|
||||
|
||||
import static org.librecms.CmsConstants.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@RequestScoped
|
||||
public class AssetFolderBrowserController {
|
||||
|
||||
private static final Logger LOGGER = LogManager
|
||||
.getLogger(AssetFolderBrowserController.class);
|
||||
|
||||
@Inject
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Inject
|
||||
private ConfigurationManager confManager;
|
||||
|
||||
@Inject
|
||||
private CategoryManager categoryManager;
|
||||
|
||||
@Inject
|
||||
private AssetTypesManager typesManager;
|
||||
|
||||
@Inject
|
||||
private FolderRepository folderRepo;
|
||||
|
||||
@Inject
|
||||
private FolderManager folderManager;
|
||||
|
||||
@Inject
|
||||
private AssetRepository assetRepo;
|
||||
|
||||
@Inject
|
||||
private AssetManager assetManager;
|
||||
|
||||
@Inject
|
||||
private GlobalizationHelper globalizationHelper;
|
||||
|
||||
private Locale defaultLocale;
|
||||
|
||||
/**
|
||||
* Initialisation method called by the CDI-Container after an instance of
|
||||
* this class has be created by the container. Sets the
|
||||
* {@link #defaultLocale} property using the the value from the
|
||||
* {@link KernelConfig}.
|
||||
*/
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
final KernelConfig kernelConfig = confManager.findConfiguration(
|
||||
KernelConfig.class);
|
||||
defaultLocale = kernelConfig.getDefaultLocale();
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
List<AssetFolderBrowserTableRow> getAssetRows(final Folder folder,
|
||||
final String orderBy,
|
||||
final String orderDirection,
|
||||
final int firstResult,
|
||||
final int maxResults) {
|
||||
final List<Folder> subFolders = findSubFolders(folder,
|
||||
"%",
|
||||
orderBy,
|
||||
orderDirection,
|
||||
firstResult,
|
||||
maxResults);
|
||||
final List<AssetFolderBrowserTableRow> subFolderRows = subFolders
|
||||
.stream()
|
||||
.map(subFolder -> buildRow(subFolder))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (subFolders.size() > maxResults) {
|
||||
return subFolderRows;
|
||||
} else {
|
||||
final int maxAssets = maxResults - subFolders.size();
|
||||
final int firstAsset = firstResult - subFolders.size();
|
||||
|
||||
final List<Asset> assets = findAssetsInFolder(folder,
|
||||
"%",
|
||||
orderBy,
|
||||
orderDirection,
|
||||
firstAsset,
|
||||
maxAssets);
|
||||
final List<AssetFolderBrowserTableRow> assetRows = assets
|
||||
.stream()
|
||||
.map(asset -> buildRow(asset))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
final List<AssetFolderBrowserTableRow> rows = new ArrayList<>();
|
||||
rows.addAll(subFolderRows);
|
||||
rows.addAll(assetRows);
|
||||
|
||||
return rows;
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
protected long countObjects(final Folder folder) {
|
||||
|
||||
return countObjects(folder, "%");
|
||||
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
protected long countObjects(final Folder folder, final String filterTerm) {
|
||||
|
||||
Objects.requireNonNull(folder);
|
||||
Objects.requireNonNull(filterTerm);
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<Long> criteriaQuery = builder.createQuery(Long.class);
|
||||
final Root<CcmObject> from = criteriaQuery.from(CcmObject.class);
|
||||
|
||||
criteriaQuery = criteriaQuery.select(builder.count(from));
|
||||
|
||||
final List<Folder> subFolders = findSubFolders(
|
||||
folder,
|
||||
filterTerm,
|
||||
AssetFolderBrowser.SORT_KEY_NAME,
|
||||
AssetFolderBrowser.SORT_ACTION_UP,
|
||||
-1,
|
||||
-1);
|
||||
final List<Asset> assets = findAssetsInFolder(
|
||||
folder,
|
||||
filterTerm,
|
||||
AssetFolderBrowser.SORT_KEY_NAME,
|
||||
AssetFolderBrowser.SORT_ACTION_UP,
|
||||
-1,
|
||||
-1);
|
||||
|
||||
if (subFolders.isEmpty() && assets.isEmpty()) {
|
||||
return 0;
|
||||
} else if (subFolders.isEmpty() && !assets.isEmpty()) {
|
||||
criteriaQuery = criteriaQuery.where(from.in(assets));
|
||||
} else if (!subFolders.isEmpty() && assets.isEmpty()) {
|
||||
criteriaQuery = criteriaQuery.where(from.in(subFolders));
|
||||
} else {
|
||||
criteriaQuery = criteriaQuery.where(builder.or(
|
||||
from.in(subFolders),
|
||||
from.in(assets)));
|
||||
}
|
||||
|
||||
return entityManager.createQuery(criteriaQuery).getSingleResult();
|
||||
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
protected void copyObjects(final Folder targetFolder,
|
||||
final String[] objectIds) {
|
||||
|
||||
Objects.requireNonNull(targetFolder);
|
||||
Objects.requireNonNull(objectIds);
|
||||
|
||||
for (final String objectId : objectIds) {
|
||||
if (objectId.startsWith(FOLDER_BROWSER_KEY_PREFIX_FOLDER)) {
|
||||
copyFolder(targetFolder,
|
||||
Long.parseLong(objectId.substring(
|
||||
FOLDER_BROWSER_KEY_PREFIX_FOLDER.length())));
|
||||
} else if (objectId.startsWith(FOLDER_BROWSER_KEY_PREFIX_ASSET)) {
|
||||
copyAsset(targetFolder,
|
||||
Long.parseLong(objectId.substring(
|
||||
FOLDER_BROWSER_KEY_PREFIX_ASSET.length())));
|
||||
} else {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"ID '%s' does not start with '%s' or '%s'.",
|
||||
objectId,
|
||||
FOLDER_BROWSER_KEY_PREFIX_FOLDER,
|
||||
FOLDER_BROWSER_KEY_PREFIX_ASSET));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void copyFolder(final Folder targetFolder,
|
||||
final long folderId) {
|
||||
|
||||
Objects.requireNonNull(targetFolder);
|
||||
|
||||
final Folder folder = folderRepo.findById(folderId)
|
||||
.orElseThrow(() -> new IllegalArgumentException(String.format(
|
||||
"No folder with ID %d in the database. "
|
||||
+ "Where did that ID come from?",
|
||||
folderId)));
|
||||
|
||||
folderManager.copyFolder(folder, targetFolder);
|
||||
|
||||
}
|
||||
|
||||
private void copyAsset(final Folder targetFolder,
|
||||
final long assetId) {
|
||||
|
||||
Objects.requireNonNull(targetFolder);
|
||||
|
||||
final Asset asset = assetRepo
|
||||
.findById(assetId)
|
||||
.orElseThrow(() -> new IllegalArgumentException(String.format(
|
||||
"No asset ith ID %d in the database. Where did that ID come from?",
|
||||
assetId)));
|
||||
|
||||
assetManager.copy(asset, targetFolder);
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public void moveObjects(final Folder targetFolder,
|
||||
final String[] objectIds) {
|
||||
|
||||
Objects.requireNonNull(targetFolder);
|
||||
Objects.requireNonNull(objectIds);
|
||||
|
||||
for (final String objectId : objectIds) {
|
||||
if (objectId.startsWith(FOLDER_BROWSER_KEY_PREFIX_FOLDER)) {
|
||||
moveFolder(targetFolder,
|
||||
Long.parseLong(objectId.substring(
|
||||
FOLDER_BROWSER_KEY_PREFIX_FOLDER.length())));
|
||||
} else if (objectId.startsWith(FOLDER_BROWSER_KEY_PREFIX_ASSET)) {
|
||||
moveAsset(targetFolder,
|
||||
Long.parseLong(objectId.substring(
|
||||
FOLDER_BROWSER_KEY_PREFIX_ASSET.length())));
|
||||
} else {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"ID '%s' does not start with '%s' or '%s'.",
|
||||
objectId,
|
||||
FOLDER_BROWSER_KEY_PREFIX_FOLDER,
|
||||
FOLDER_BROWSER_KEY_PREFIX_ASSET));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void moveFolder(final Folder targetFolder, final long folderId) {
|
||||
|
||||
Objects.requireNonNull(targetFolder);
|
||||
|
||||
final Folder folder = folderRepo.findById(folderId)
|
||||
.orElseThrow(() -> new IllegalArgumentException(String.format(
|
||||
"No folder with ID %d in the database. "
|
||||
+ "Where did that ID come from?",
|
||||
folderId)));
|
||||
|
||||
folderManager.moveFolder(folder, targetFolder);
|
||||
}
|
||||
|
||||
private void moveAsset(final Folder targetFolder, final long assetId) {
|
||||
|
||||
Objects.requireNonNull(targetFolder);
|
||||
|
||||
final Asset asset = assetRepo
|
||||
.findById(assetId)
|
||||
.orElseThrow(() -> new IllegalArgumentException(String.format(
|
||||
"No asset with ID %d in the database. Where did that ID come from?",
|
||||
assetId)));
|
||||
|
||||
assetManager.move(asset, targetFolder);
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
protected List<String> createInvalidTargetsList(final List<String> sources) {
|
||||
|
||||
Objects.requireNonNull(sources);
|
||||
|
||||
final List<String> sourceFolderIds = sources
|
||||
.stream()
|
||||
.filter(source -> source.startsWith(
|
||||
FOLDER_BROWSER_KEY_PREFIX_FOLDER))
|
||||
.collect(Collectors.toList());
|
||||
final List<String> parentFolderIds = sourceFolderIds
|
||||
.stream()
|
||||
.map(sourceFolderId -> findParentFolderId(sourceFolderId))
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
.collect(Collectors.toList());
|
||||
final List<List<String>> subFolderIds = sourceFolderIds
|
||||
.stream()
|
||||
.map(sourceFolderId -> findSubFolderIds(sourceFolderId))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
final List<String> invalidTargetIds = new ArrayList<>();
|
||||
invalidTargetIds.addAll(sourceFolderIds);
|
||||
invalidTargetIds.addAll(parentFolderIds);
|
||||
for (final List<String> subFolderIdList : subFolderIds) {
|
||||
invalidTargetIds.addAll(subFolderIdList);
|
||||
}
|
||||
|
||||
return invalidTargetIds;
|
||||
|
||||
}
|
||||
|
||||
private Optional<String> findParentFolderId(final String folderId) {
|
||||
|
||||
Objects.requireNonNull(folderId);
|
||||
|
||||
if (!folderId.startsWith(FOLDER_BROWSER_KEY_PREFIX_FOLDER)) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Provided string '%s' is not an ID of a folder.",
|
||||
folderId));
|
||||
}
|
||||
|
||||
final long objectId = Long.parseLong(folderId.substring(
|
||||
FOLDER_BROWSER_KEY_PREFIX_FOLDER.length()));
|
||||
final Folder folder = folderRepo.findById(objectId)
|
||||
.orElseThrow(() -> new IllegalArgumentException(String.format(
|
||||
"No folder with ID %d found in database. "
|
||||
+ "Where did that ID come form?",
|
||||
objectId)));
|
||||
final Optional<Folder> parentFolder = folderManager.getParentFolder(
|
||||
folder);
|
||||
if (parentFolder.isPresent()) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
return Optional.ofNullable(String.format(
|
||||
"%s%d",
|
||||
FOLDER_BROWSER_KEY_PREFIX_FOLDER,
|
||||
parentFolder.get().getObjectId()));
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> findSubFolderIds(final String folderId) {
|
||||
|
||||
Objects.requireNonNull(folderId);
|
||||
|
||||
if (!folderId.startsWith(FOLDER_BROWSER_KEY_PREFIX_FOLDER)) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Provided string '%s' is not the ID of a folder.",
|
||||
folderId));
|
||||
}
|
||||
|
||||
final long objectId = Long.parseLong(folderId.substring(
|
||||
FOLDER_BROWSER_KEY_PREFIX_FOLDER.length()));
|
||||
final Folder folder = folderRepo.findById(objectId)
|
||||
.orElseThrow(() -> new IllegalArgumentException(String.format(
|
||||
"No folder with ID %d found in database. "
|
||||
+ "Where did that ID come form?",
|
||||
objectId)));
|
||||
return findSubFolders(folder)
|
||||
.stream()
|
||||
.map(subFolder -> String.format("%s%d",
|
||||
FOLDER_BROWSER_KEY_PREFIX_FOLDER,
|
||||
subFolder.getObjectId()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<Folder> findSubFolders(final Folder folder) {
|
||||
|
||||
Objects.requireNonNull(folder);
|
||||
|
||||
if (folder.getSubFolders() == null
|
||||
|| folder.getSubFolders().isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final List<Folder> subFolders = new ArrayList<>();
|
||||
for (final Folder subFolder : folder.getSubFolders()) {
|
||||
subFolders.add(subFolder);
|
||||
subFolders.addAll(findSubFolders(subFolder));
|
||||
}
|
||||
|
||||
return subFolders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the {@link AssetFolderBrowser} to delete an object.
|
||||
*
|
||||
* @param objectId
|
||||
*/
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
protected void deleteObject(final String objectId) {
|
||||
|
||||
Objects.requireNonNull(objectId);
|
||||
|
||||
if (objectId.startsWith("folder-")) {
|
||||
final long folderId = Long.parseLong(
|
||||
objectId.substring("folder-".length()));
|
||||
|
||||
folderRepo
|
||||
.findById(folderId)
|
||||
.ifPresent(folderRepo::delete);
|
||||
} else if (objectId.startsWith("asset-")) {
|
||||
final long assetId = Long.parseLong(
|
||||
objectId.substring("asset-".length()));
|
||||
|
||||
assetRepo
|
||||
.findById(assetId)
|
||||
.ifPresent(assetRepo::delete);
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"The objectId is expected to start with 'folder-' or 'asset-'.");
|
||||
}
|
||||
}
|
||||
|
||||
private AssetFolderBrowserTableRow buildRow(final Folder folder) {
|
||||
|
||||
final AssetFolderBrowserTableRow row = new AssetFolderBrowserTableRow();
|
||||
|
||||
row.setObjectId(folder.getObjectId());
|
||||
row.setObjectUuid(folder.getUuid());
|
||||
row.setName(folder.getName());
|
||||
if (folder.getTitle().hasValue(globalizationHelper
|
||||
.getNegotiatedLocale())) {
|
||||
row.setTitle(folder.getTitle().getValue(globalizationHelper
|
||||
.getNegotiatedLocale()));
|
||||
} else {
|
||||
row.setTitle(folder.getTitle().getValue(defaultLocale));
|
||||
}
|
||||
row.setFolder(true);
|
||||
row.setDeletable(!categoryManager.hasSubCategories(folder)
|
||||
&& !categoryManager.hasObjects(folder));
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
private AssetFolderBrowserTableRow buildRow(final Asset asset) {
|
||||
|
||||
final AssetFolderBrowserTableRow row = new AssetFolderBrowserTableRow();
|
||||
|
||||
row.setObjectId(asset.getObjectId());
|
||||
row.setObjectUuid(asset.getUuid());
|
||||
row.setName(asset.getDisplayName());
|
||||
if (asset.getTitle().hasValue(globalizationHelper
|
||||
.getNegotiatedLocale())) {
|
||||
row.setTitle(asset.getTitle().getValue(globalizationHelper
|
||||
.getNegotiatedLocale()));
|
||||
} else {
|
||||
row.setTitle(asset.getTitle().getValue(defaultLocale));
|
||||
}
|
||||
if (asset instanceof Image) {
|
||||
row.setThumbnailUrl(String
|
||||
.format("%s/content-sections/%s/images/"
|
||||
+ "uuid-%s?width=150&height=100",
|
||||
CCMDispatcherServlet.getContextPath(),
|
||||
CMS.getContext().getContentSection().getLabel(),
|
||||
asset.getUuid()));
|
||||
}
|
||||
final AssetTypeInfo typeInfo = typesManager
|
||||
.getAssetTypeInfo(asset.getClass());
|
||||
row.setTypeLabelBundle(typeInfo.getLabelBundle());
|
||||
row.setTypeLabelKey(typeInfo.getLabelKey());
|
||||
|
||||
row.setFolder(false);
|
||||
|
||||
row.setDeletable(!assetManager.isAssetInUse(asset));
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
private List<Folder> findSubFolders(final Folder folder,
|
||||
final String filterTerm,
|
||||
final String orderBy,
|
||||
final String orderDirection,
|
||||
final int firstResult,
|
||||
final int maxResults) {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
|
||||
final CriteriaQuery<Folder> criteria = builder
|
||||
.createQuery(Folder.class);
|
||||
final Root<Folder> from = criteria.from(Folder.class);
|
||||
|
||||
final Order order;
|
||||
if (AssetFolderBrowser.SORT_KEY_NAME.equals(orderBy)
|
||||
&& AssetFolderBrowser.SORT_ACTION_DOWN.
|
||||
equals(orderDirection)) {
|
||||
order = builder.desc(from.get("name"));
|
||||
} else {
|
||||
order = builder.asc(from.get("name"));
|
||||
}
|
||||
|
||||
final TypedQuery<Folder> query = entityManager
|
||||
.createQuery(
|
||||
criteria.where(
|
||||
builder.and(
|
||||
builder.
|
||||
equal(from.get("parentCategory"),
|
||||
folder),
|
||||
builder.like(builder.lower(from.get(
|
||||
"name")),
|
||||
filterTerm)
|
||||
)
|
||||
)
|
||||
.orderBy(order)
|
||||
);
|
||||
|
||||
if (firstResult >= 0) {
|
||||
query.setFirstResult(firstResult);
|
||||
}
|
||||
|
||||
if (maxResults >= 0) {
|
||||
query.setMaxResults(maxResults);
|
||||
}
|
||||
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
private List<Asset> findAssetsInFolder(final Folder folder,
|
||||
final String filterTerm,
|
||||
final String orderBy,
|
||||
final String orderDirection,
|
||||
final int firstResult,
|
||||
final int maxResults) {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
|
||||
final CriteriaQuery<Asset> criteria = builder.createQuery(Asset.class);
|
||||
final Root<Asset> fromAsset = criteria.from(Asset.class);
|
||||
final Join<Asset, Category> join = fromAsset.join("categories");
|
||||
|
||||
final Path<?> orderPath;
|
||||
switch (orderBy) {
|
||||
case AssetFolderBrowser.SORT_KEY_NAME:
|
||||
orderPath = fromAsset.get("displayName");
|
||||
break;
|
||||
case AssetFolderBrowser.SORT_KEY_CREATION_DATE:
|
||||
orderPath = fromAsset.get("creationDate");
|
||||
break;
|
||||
case AssetFolderBrowser.SORT_KEY_LAST_MODIFIED_DATE:
|
||||
orderPath = fromAsset.get("lastModifed");
|
||||
break;
|
||||
default:
|
||||
orderPath = fromAsset.get("displayName");
|
||||
break;
|
||||
}
|
||||
|
||||
final Order order;
|
||||
if (AssetFolderBrowser.SORT_ACTION_DOWN.equals(orderDirection)) {
|
||||
order = builder.desc(orderPath);
|
||||
} else {
|
||||
order = builder.asc(orderPath);
|
||||
}
|
||||
|
||||
LOGGER.debug("The database contains {} assets.",
|
||||
entityManager.createQuery(criteria.select(fromAsset)
|
||||
.where(
|
||||
builder.and(
|
||||
builder.equal(join.get("category"),
|
||||
folder),
|
||||
builder.equal(join.get("type"),
|
||||
CmsConstants.CATEGORIZATION_TYPE_FOLDER),
|
||||
builder.like(builder.lower(
|
||||
fromAsset.get(
|
||||
"displayName")),
|
||||
filterTerm)
|
||||
))).getResultList().size());
|
||||
|
||||
final TypedQuery<Asset> query = entityManager
|
||||
.createQuery(
|
||||
criteria.select(fromAsset)
|
||||
.where(
|
||||
builder.and(
|
||||
builder.equal(join.get(
|
||||
"category"), folder),
|
||||
builder.equal(join.get("type"),
|
||||
CmsConstants.CATEGORIZATION_TYPE_FOLDER),
|
||||
builder.like(builder.lower(
|
||||
fromAsset.get(
|
||||
"displayName")),
|
||||
filterTerm)
|
||||
)
|
||||
)
|
||||
.orderBy(order)
|
||||
);
|
||||
|
||||
if (firstResult >= 0) {
|
||||
query.setFirstResult(firstResult);
|
||||
}
|
||||
|
||||
if (maxResults >= 0) {
|
||||
query.setMaxResults(maxResults);
|
||||
}
|
||||
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* 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.assets;
|
||||
|
||||
import com.arsdigita.bebop.PageState;
|
||||
import com.arsdigita.bebop.PaginationModelBuilder;
|
||||
import com.arsdigita.bebop.Paginator;
|
||||
import com.arsdigita.cms.ui.folder.FolderSelectionModel;
|
||||
import org.libreccm.cdi.utils.CdiUtil;
|
||||
import org.librecms.contentsection.Folder;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class AssetFolderBrowserPaginationModelBuilder implements PaginationModelBuilder {
|
||||
|
||||
private final AssetFolderBrowser folderBrowser;
|
||||
|
||||
public AssetFolderBrowserPaginationModelBuilder(
|
||||
final AssetFolderBrowser folderBrowser) {
|
||||
|
||||
this.folderBrowser = folderBrowser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTotalSize(final Paginator paginator, final PageState state) {
|
||||
|
||||
final FolderSelectionModel folderSelectionModel = folderBrowser
|
||||
.getFolderSelectionModel();
|
||||
final Folder folder = folderSelectionModel.getSelectedObject(state);
|
||||
if (folder == null) {
|
||||
return 0;
|
||||
} else {
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final AssetFolderBrowserController controller = cdiUtil.findBean(
|
||||
AssetFolderBrowserController.class);
|
||||
return (int) controller.countObjects(folder);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisible(final PageState state) {
|
||||
return folderBrowser != null && folderBrowser.isVisible(state);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
/*
|
||||
* 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.assets;
|
||||
|
||||
import com.arsdigita.bebop.table.TableModel;
|
||||
import com.arsdigita.globalization.GlobalizedMessage;
|
||||
|
||||
import org.librecms.CmsConstants;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class AssetFolderBrowserTableModel implements TableModel {
|
||||
|
||||
protected static final int COL_NAME = 0;
|
||||
protected static final int COL_TITLE = 1;
|
||||
protected static final int COL_TYPE = 2;
|
||||
protected static final int COL_THUMBNAIL = 3;
|
||||
protected static final int COL_CREATION_DATE = 4;
|
||||
protected static final int COL_LAST_MODIFIED = 5;
|
||||
protected static final int COL_DELETEABLE = 6;
|
||||
|
||||
private final Iterator<AssetFolderBrowserTableRow> iterator;
|
||||
private AssetFolderBrowserTableRow currentRow;
|
||||
|
||||
public AssetFolderBrowserTableModel(
|
||||
final List<AssetFolderBrowserTableRow> rows) {
|
||||
|
||||
iterator = rows.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return 6;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nextRow() {
|
||||
if (iterator.hasNext()) {
|
||||
currentRow = iterator.next();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getElementAt(final int columnIndex) {
|
||||
switch (columnIndex) {
|
||||
case COL_NAME:
|
||||
return currentRow.getName();
|
||||
case COL_TITLE:
|
||||
return currentRow.getTitle();
|
||||
case COL_TYPE:
|
||||
final String typeLabelBundle = currentRow.getTypeLabelBundle();
|
||||
final String typeLabelKey = currentRow.getTypeLabelKey();
|
||||
if (typeLabelKey == null) {
|
||||
return new GlobalizedMessage("empty_text",
|
||||
CmsConstants.CMS_BUNDLE);
|
||||
} else {
|
||||
return new GlobalizedMessage(typeLabelKey, typeLabelBundle);
|
||||
}
|
||||
case COL_THUMBNAIL:
|
||||
return currentRow.getThumbnailUrl();
|
||||
case COL_CREATION_DATE:
|
||||
return currentRow.getCreated();
|
||||
case COL_LAST_MODIFIED:
|
||||
return currentRow.getLastModified();
|
||||
case COL_DELETEABLE:
|
||||
return currentRow.isDeletable();
|
||||
default:
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Illegal column index %d.", columnIndex));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getKeyAt(final int columnIndex) {
|
||||
if (currentRow.isFolder()) {
|
||||
return String.format("folder-%d", currentRow.getObjectId());
|
||||
} else {
|
||||
return String.format("asset-%d", currentRow.getObjectId());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFolder() {
|
||||
return currentRow.isFolder();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
/*
|
||||
* 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.assets;
|
||||
|
||||
import com.arsdigita.bebop.PageState;
|
||||
import com.arsdigita.bebop.Paginator;
|
||||
import com.arsdigita.bebop.Table;
|
||||
import com.arsdigita.bebop.table.TableModel;
|
||||
import com.arsdigita.bebop.table.TableModelBuilder;
|
||||
import com.arsdigita.cms.ui.folder.FolderSelectionModel;
|
||||
import com.arsdigita.util.LockableImpl;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.libreccm.cdi.utils.CdiUtil;
|
||||
import org.librecms.contentsection.Folder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Creates the {@link TableModel} for the {@link AssetFolderBrowser}.
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class AssetFolderBrowserTableModelBuilder
|
||||
extends LockableImpl
|
||||
implements TableModelBuilder {
|
||||
|
||||
private static final Logger LOGGER = LogManager
|
||||
.getLogger(AssetFolderBrowserTableModelBuilder.class);
|
||||
|
||||
@Override
|
||||
public TableModel makeModel(final Table table,
|
||||
final PageState state) {
|
||||
|
||||
if (!(table instanceof AssetFolderBrowser)) {
|
||||
throw new IllegalArgumentException(
|
||||
"The AssetFolderBrowserTableModelBuilder can only be used "
|
||||
+ "for the AssetFolderBrowser.");
|
||||
}
|
||||
|
||||
final AssetFolderBrowser assetFolderBrowser = (AssetFolderBrowser) table;
|
||||
final FolderSelectionModel folderSelectionModel = assetFolderBrowser
|
||||
.getFolderSelectionModel();
|
||||
final Folder folder = folderSelectionModel.getSelectedObject(state);
|
||||
if (folder == null) {
|
||||
return Table.EMPTY_MODEL;
|
||||
} else {
|
||||
assetFolderBrowser.getRowSelectionModel().clearSelection(state);
|
||||
final Paginator paginator = assetFolderBrowser.getPaginator();
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final AssetFolderBrowserController controller = cdiUtil
|
||||
.findBean(AssetFolderBrowserController.class);
|
||||
final String orderBy;
|
||||
if (assetFolderBrowser.getSortType(state) == null) {
|
||||
orderBy = AssetFolderBrowser.SORT_KEY_NAME;
|
||||
} else {
|
||||
orderBy = assetFolderBrowser.getSortType(state);
|
||||
}
|
||||
final String orderDirection;
|
||||
if (assetFolderBrowser.getSortDirection(state) == null) {
|
||||
orderDirection = AssetFolderBrowser.SORT_ACTION_UP;
|
||||
} else {
|
||||
orderDirection = assetFolderBrowser.getSortDirection(state);
|
||||
}
|
||||
final int first = paginator.getFirst(state);
|
||||
final int pageSize = paginator.getPageSize(state);
|
||||
|
||||
final long start = System.nanoTime();
|
||||
LOGGER.debug("Retrieving table rows...");
|
||||
final List<AssetFolderBrowserTableRow> rows = controller
|
||||
.getAssetRows(folder,
|
||||
orderBy,
|
||||
orderDirection,
|
||||
first - 1,
|
||||
pageSize);
|
||||
|
||||
LOGGER.debug("Retrieve table rows in {} ms.",
|
||||
(System.nanoTime() - start) / 1000);
|
||||
return new AssetFolderBrowserTableModel(rows);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,148 +0,0 @@
|
|||
/*
|
||||
* 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.assets;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class AssetFolderBrowserTableRow {
|
||||
|
||||
private long objectId;
|
||||
private String objectUuid;
|
||||
private String name;
|
||||
private String title;
|
||||
private String thumbnailUrl;
|
||||
private String typeLabelBundle;
|
||||
private String typeLabelKey;
|
||||
private Date created;
|
||||
private Date lastModified;
|
||||
private boolean deletable;
|
||||
private boolean folder;
|
||||
|
||||
public long getObjectId() {
|
||||
return objectId;
|
||||
}
|
||||
|
||||
public void setObjectId(final long objectId) {
|
||||
this.objectId = objectId;
|
||||
}
|
||||
|
||||
public String getObjectUuid() {
|
||||
return objectUuid;
|
||||
}
|
||||
|
||||
public void setObjectUuid(final String objectUuid) {
|
||||
this.objectUuid = objectUuid;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(final String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getThumbnailUrl() {
|
||||
return thumbnailUrl;
|
||||
}
|
||||
|
||||
public void setThumbnailUrl(final String thumbnailUrl) {
|
||||
this.thumbnailUrl = thumbnailUrl;
|
||||
}
|
||||
|
||||
public String getTypeLabelBundle() {
|
||||
return typeLabelBundle;
|
||||
}
|
||||
|
||||
public void setTypeLabelBundle(final String typeLabelBundle) {
|
||||
this.typeLabelBundle = typeLabelBundle;
|
||||
}
|
||||
|
||||
public String getTypeLabelKey() {
|
||||
return typeLabelKey;
|
||||
}
|
||||
|
||||
public void setTypeLabelKey(final String typeLabelKey) {
|
||||
this.typeLabelKey = typeLabelKey;
|
||||
}
|
||||
|
||||
public Date getCreated() {
|
||||
if (created == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new Date(created.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
protected void setCreated(final Date created) {
|
||||
if (created == null) {
|
||||
this.created = null;
|
||||
} else {
|
||||
this.created = new Date(created.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
public Date getLastModified() {
|
||||
if (lastModified == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new Date(lastModified.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
protected void setLastModified(final Date lastModified) {
|
||||
if (lastModified == null) {
|
||||
this.lastModified = null;
|
||||
} else {
|
||||
this.lastModified = new Date(lastModified.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDeletable() {
|
||||
return deletable;
|
||||
}
|
||||
|
||||
public void setDeletable(final boolean deletable) {
|
||||
this.deletable = deletable;
|
||||
}
|
||||
|
||||
public boolean isFolder() {
|
||||
return folder;
|
||||
}
|
||||
|
||||
public void setFolder(final boolean folder) {
|
||||
this.folder = folder;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
/*
|
||||
* 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.assets;
|
||||
|
||||
import org.librecms.contentsection.Asset;
|
||||
import org.librecms.contentsection.Folder;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* Interface for the CDI backend for the forms to manage assets.To avoid
|
||||
* problems with transactions etc.
|
||||
*
|
||||
* the Bebop based forms should access any other CDI beans beside the
|
||||
* approbriate implementation of this interface. To minimize the efford to
|
||||
* create an implementation the {@link AbstractAssetFormController} class should
|
||||
* be used. This class provides basic implementations for most methods.
|
||||
*
|
||||
* Implementations of the methods defined by this interface should annotated
|
||||
* with {@code @Transactional(Transactional.TxType.REQUIRED)}.
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*
|
||||
* @param <T> The type asset managed by this controller.
|
||||
*/
|
||||
public interface AssetFormController<T extends Asset> {
|
||||
|
||||
/**
|
||||
* Gets the data for the forms from the asset.
|
||||
*
|
||||
* @param assetId The ID of the asset.
|
||||
* @param assetType
|
||||
* @param selectedLocale The selected locale
|
||||
*
|
||||
* @return The values of the properties of the asset for the the selected
|
||||
* locale.
|
||||
*/
|
||||
Map<String, Object> getAssetData(Long assetId,
|
||||
Class<T> assetType,
|
||||
Locale selectedLocale);
|
||||
|
||||
/**
|
||||
* Updates the asset with the provided data and saves the changes.
|
||||
*
|
||||
* @param assetId
|
||||
* @param selectedLocale
|
||||
* @param assetType
|
||||
* @param data
|
||||
*/
|
||||
void updateAsset(Long assetId,
|
||||
Locale selectedLocale,
|
||||
Class<T> assetType,
|
||||
Map<String, Object> data);
|
||||
|
||||
long createAsset(Folder inFolder,
|
||||
Locale selectedLocale,
|
||||
Class<T> assetType,
|
||||
Map<String, Object> data);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Determines in which locales the provided asset is available.
|
||||
*
|
||||
*
|
||||
* @param assetId
|
||||
* @param assetType
|
||||
*
|
||||
* @return A list of the locales for which the asset has data.
|
||||
*/
|
||||
List<Locale> availableLocales(Long assetId, Class<T> assetType);
|
||||
|
||||
/**
|
||||
* Determines for which the provided asset has no data.
|
||||
*
|
||||
*
|
||||
* @param assetId
|
||||
* @param assetType
|
||||
*
|
||||
* @return A list of the locales for which the asset has data yet.
|
||||
*/
|
||||
List<Locale> creatableLocales(Long assetId, Class<T> assetType);
|
||||
|
||||
void addLocale(final Long assetId,
|
||||
final Locale locale,
|
||||
final Class<T> assetType);
|
||||
|
||||
}
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 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.assets;
|
||||
|
||||
import org.librecms.contentsection.Asset;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.enterprise.inject.Any;
|
||||
import javax.enterprise.inject.Instance;
|
||||
import javax.enterprise.util.AnnotationLiteral;
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@RequestScoped
|
||||
public class AssetFormControllers {
|
||||
|
||||
@Inject
|
||||
@Any
|
||||
private Instance<AssetFormController<?>> controllers;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Asset> AssetFormController<T> findController(
|
||||
final Class<T> assetType) {
|
||||
|
||||
final IsControllerForAssetTypeLiteral literal
|
||||
= new IsControllerForAssetTypeLiteral(
|
||||
assetType);
|
||||
|
||||
final Instance<AssetFormController<?>> instance = controllers
|
||||
.select(literal);
|
||||
|
||||
if (instance.isUnsatisfied()) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"No controller for asset type \"%s\".",
|
||||
assetType.getClass().getName()));
|
||||
} else {
|
||||
return (AssetFormController<T>) instance.iterator().next();
|
||||
}
|
||||
}
|
||||
|
||||
private class IsControllerForAssetTypeLiteral
|
||||
extends AnnotationLiteral<IsControllerForAssetType>
|
||||
implements IsControllerForAssetType {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final Class<? extends Asset> assetType;
|
||||
|
||||
public IsControllerForAssetTypeLiteral(
|
||||
final Class<? extends Asset> assetType) {
|
||||
|
||||
this.assetType = assetType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Asset> value() {
|
||||
|
||||
return assetType;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,114 +0,0 @@
|
|||
/*
|
||||
* 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.assets;
|
||||
|
||||
import com.arsdigita.bebop.PageState;
|
||||
import com.arsdigita.bebop.form.Widget;
|
||||
import com.arsdigita.bebop.parameters.LongParameter;
|
||||
import com.arsdigita.cms.CMS;
|
||||
import com.arsdigita.xml.Element;
|
||||
|
||||
import org.libreccm.cdi.utils.CdiUtil;
|
||||
import org.libreccm.l10n.GlobalizationHelper;
|
||||
import org.librecms.assets.AssetTypeInfo;
|
||||
import org.librecms.assets.AssetTypesManager;
|
||||
import org.librecms.contentsection.Asset;
|
||||
import org.librecms.contentsection.AssetRepository;
|
||||
import org.librecms.contentsection.ContentSection;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* A widget for selecting an asset. The widget does not contain any other
|
||||
* widgets, only the information required to create an HTML/JavaScript dialog
|
||||
* for selecting an asset. To create the dialog the
|
||||
* {@link org.librecms.contentsection.rs.Assets} class can be used which
|
||||
* provides several methods for getting the assets of an content section.
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class AssetSearchWidget extends Widget {
|
||||
|
||||
private Class<? extends Asset> type;
|
||||
|
||||
public AssetSearchWidget(final String name) {
|
||||
super(new LongParameter(name));
|
||||
}
|
||||
|
||||
public AssetSearchWidget(final String name,
|
||||
final Class<? extends Asset> type) {
|
||||
this(name);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompound() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getType() {
|
||||
return "asset-search-widget";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getElementTag() {
|
||||
return "cms:asset-search-widget";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateWidget(final PageState state,
|
||||
final Element parent) {
|
||||
|
||||
final Element widget = parent.newChildElement(getElementTag(),
|
||||
CMS.CMS_XML_NS);
|
||||
|
||||
widget.addAttribute("name", getName());
|
||||
|
||||
if (type != null) {
|
||||
widget.addAttribute("asset-type", type.getName());
|
||||
}
|
||||
|
||||
final ContentSection section = CMS.getContext().getContentSection();
|
||||
widget.addAttribute("content-section", section.getLabel());
|
||||
|
||||
final Long value = (Long) getValue(state);
|
||||
if (value != null) {
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final AssetSearchWidgetController controller = cdiUtil
|
||||
.findBean(AssetSearchWidgetController.class);
|
||||
|
||||
final Map<String, String> data = controller.getData(value);
|
||||
|
||||
final Element selected = widget
|
||||
.newChildElement("cms:selected-asset", CMS.CMS_XML_NS);
|
||||
selected.addAttribute(
|
||||
"assetId", data.get(AssetSearchWidgetController.OBJECT_ID)
|
||||
);
|
||||
selected.addAttribute("title",
|
||||
data.get(AssetSearchWidgetController.TITLE));
|
||||
selected.addAttribute("type",
|
||||
data.get(AssetSearchWidgetController.TYPE));
|
||||
|
||||
exportAttributes(widget);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 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.assets;
|
||||
|
||||
import org.libreccm.l10n.GlobalizationHelper;
|
||||
import org.librecms.assets.AssetTypeInfo;
|
||||
import org.librecms.assets.AssetTypesManager;
|
||||
import org.librecms.contentsection.Asset;
|
||||
import org.librecms.contentsection.AssetRepository;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.inject.Inject;
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@RequestScoped
|
||||
public class AssetSearchWidgetController {
|
||||
|
||||
protected static final String OBJECT_ID = "objectId";
|
||||
protected static final String TYPE = "type";
|
||||
protected static final String TITLE = "title";
|
||||
|
||||
@Inject
|
||||
private AssetRepository assetRepository;
|
||||
|
||||
@Inject
|
||||
private AssetTypesManager typesManager;
|
||||
|
||||
@Inject
|
||||
private GlobalizationHelper globalizationHelper;
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public Map<String, String> getData(final long assetId) {
|
||||
|
||||
final Asset asset = assetRepository
|
||||
.findById(assetId)
|
||||
.orElseThrow(() -> new IllegalArgumentException(String.format(
|
||||
"No Asset with ID %d in the database.", assetId)));
|
||||
|
||||
final Map<String, String> data = new HashMap<>();
|
||||
|
||||
data.put(OBJECT_ID, Long.toString(asset.getObjectId()));
|
||||
|
||||
data.put(TITLE,
|
||||
globalizationHelper
|
||||
.getValueFromLocalizedString(asset.getTitle()));
|
||||
final AssetTypeInfo typeInfo = typesManager
|
||||
.getAssetTypeInfo(asset.getClass().getName());
|
||||
final ResourceBundle bundle = ResourceBundle
|
||||
.getBundle(typeInfo.getLabelBundle(),
|
||||
globalizationHelper.getNegotiatedLocale());
|
||||
final String typeLabel = bundle.getString(typeInfo.getLabelKey());
|
||||
|
||||
data.put(TYPE, typeLabel);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 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.assets;
|
||||
|
||||
import org.librecms.contentsection.Asset;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@Qualifier
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({
|
||||
ElementType.METHOD,
|
||||
ElementType.FIELD,
|
||||
ElementType.PARAMETER,
|
||||
ElementType.TYPE
|
||||
})
|
||||
public @interface IsControllerForAssetType {
|
||||
|
||||
Class<? extends Asset> value();
|
||||
|
||||
}
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
/*
|
||||
* 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.assets;
|
||||
|
||||
import com.arsdigita.bebop.PageState;
|
||||
import com.arsdigita.bebop.form.Widget;
|
||||
import com.arsdigita.bebop.parameters.LongParameter;
|
||||
import com.arsdigita.cms.CMS;
|
||||
import com.arsdigita.xml.Element;
|
||||
|
||||
import org.libreccm.cdi.utils.CdiUtil;
|
||||
import org.libreccm.l10n.GlobalizationHelper;
|
||||
import org.librecms.contentsection.ContentItem;
|
||||
import org.librecms.contentsection.ContentItemRepository;
|
||||
import org.librecms.contentsection.ContentSection;
|
||||
import org.librecms.contenttypes.ContentTypeInfo;
|
||||
import org.librecms.contenttypes.ContentTypesManager;
|
||||
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class ItemSearchWidget extends Widget {
|
||||
|
||||
private Class<? extends ContentItem> type;
|
||||
|
||||
public ItemSearchWidget(final String name) {
|
||||
super(new LongParameter(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompound() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getType() {
|
||||
return "item-search-widget";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getElementTag() {
|
||||
return "cms:item-search-widget";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateWidget(final PageState state,
|
||||
final Element parent) {
|
||||
|
||||
final Element widget = parent.newChildElement(getElementTag(),
|
||||
CMS.CMS_XML_NS);
|
||||
|
||||
widget.addAttribute("name", getName());
|
||||
widget.addAttribute("content-section",
|
||||
CMS.getContext().getContentSection().getLabel());
|
||||
|
||||
if (type != null) {
|
||||
widget.addAttribute("asset-type", type.getName());
|
||||
}
|
||||
|
||||
// final ContentSection section = CMS.getContext().getContentSection();
|
||||
// widget.addAttribute("content-section", section.getLabel());
|
||||
|
||||
final Long value = (Long) getValue(state);
|
||||
if (value != null) {
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final ContentItemRepository itemRepo = cdiUtil
|
||||
.findBean(ContentItemRepository.class);
|
||||
final ContentTypesManager typesManager = cdiUtil
|
||||
.findBean(ContentTypesManager.class);
|
||||
final GlobalizationHelper globalizationHelper = cdiUtil
|
||||
.findBean(GlobalizationHelper.class);
|
||||
|
||||
final ContentItem item = itemRepo
|
||||
.findById(value)
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No ContentItem with ID %d in the database.", value)));
|
||||
|
||||
final Element selected = widget
|
||||
.newChildElement("cms:selected-content-item", CMS.CMS_XML_NS);
|
||||
selected.addAttribute("contentItemId",
|
||||
Long.toString(item.getObjectId()));
|
||||
selected.addAttribute("name", item.getDisplayName());
|
||||
selected.addAttribute(
|
||||
"title",
|
||||
globalizationHelper.getValueFromLocalizedString(item.getTitle()));
|
||||
final ContentTypeInfo typeInfo = typesManager
|
||||
.getContentTypeInfo(item.getClass());
|
||||
final ResourceBundle bundle = ResourceBundle
|
||||
.getBundle(typeInfo.getLabelBundle(),
|
||||
globalizationHelper.getNegotiatedLocale());
|
||||
final String typeLabel = bundle.getString(typeInfo.getLabelKey());
|
||||
selected.addAttribute("type", typeLabel);
|
||||
|
||||
exportAttributes(widget);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
package org.librecms.assets;
|
||||
|
||||
import com.arsdigita.cms.ui.assets.AbstractAssetForm;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
|
|
|
|||
|
|
@ -18,8 +18,6 @@
|
|||
*/
|
||||
package org.librecms.assets;
|
||||
|
||||
import com.arsdigita.cms.ui.assets.AbstractAssetForm;
|
||||
|
||||
import org.librecms.contentsection.Asset;
|
||||
|
||||
import java.util.Objects;
|
||||
|
|
@ -56,11 +54,6 @@ public class AssetTypeInfo {
|
|||
*/
|
||||
private Class<? extends Asset> assetClass;
|
||||
|
||||
/**
|
||||
* The form for editing and creating asset of the type described.
|
||||
*/
|
||||
private Class<? extends AbstractAssetForm> assetForm;
|
||||
|
||||
public String getLabelBundle() {
|
||||
return labelBundle;
|
||||
}
|
||||
|
|
@ -101,14 +94,6 @@ public class AssetTypeInfo {
|
|||
this.assetClass = assetClass;
|
||||
}
|
||||
|
||||
public Class<? extends AbstractAssetForm> getAssetForm() {
|
||||
return assetForm;
|
||||
}
|
||||
|
||||
public void setAssetForm(final Class<? extends AbstractAssetForm> assetForm) {
|
||||
this.assetForm = assetForm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 5;
|
||||
|
|
@ -117,7 +102,6 @@ public class AssetTypeInfo {
|
|||
hash = 59 * hash + Objects.hashCode(descriptionBundle);
|
||||
hash = 59 * hash + Objects.hashCode(descriptionKey);
|
||||
hash = 59 * hash + Objects.hashCode(assetClass);
|
||||
hash = 59 * hash + Objects.hashCode(assetForm);
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
|
@ -148,38 +132,35 @@ public class AssetTypeInfo {
|
|||
if (!Objects.equals(descriptionKey, other.getDescriptionKey())) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(assetClass, other.getAssetClass())) {
|
||||
return false;
|
||||
}
|
||||
return Objects.equals(assetForm, other.getAssetForm());
|
||||
return Objects.equals(assetClass, other.getAssetClass());
|
||||
}
|
||||
|
||||
|
||||
private boolean canEqual(final Object obj) {
|
||||
return obj instanceof AssetTypeInfo;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
return toString("");
|
||||
}
|
||||
|
||||
|
||||
public String toString(final String data) {
|
||||
return String.format("%s{ "
|
||||
+ "labelBundle = \"%s\", "
|
||||
+ "labelKey = \"%s\", "
|
||||
+ "descriptionBundle = \"%s\", "
|
||||
+ "descriptionKey = \"%s\", "
|
||||
+ "assetClass = \"%s\", "
|
||||
+ "assetForm = \"%s\"%s "
|
||||
+ " }",
|
||||
super.toString(),
|
||||
labelBundle,
|
||||
labelKey,
|
||||
descriptionBundle,
|
||||
descriptionKey,
|
||||
Objects.toString(assetClass),
|
||||
Objects.toString(assetForm),
|
||||
data);
|
||||
return String.format(
|
||||
"%s{ "
|
||||
+ "labelBundle = \"%s\", "
|
||||
+ "labelKey = \"%s\", "
|
||||
+ "descriptionBundle = \"%s\", "
|
||||
+ "descriptionKey = \"%s\", "
|
||||
+ "assetClass = \"%s\"%s "
|
||||
+ " }",
|
||||
super.toString(),
|
||||
labelBundle,
|
||||
labelKey,
|
||||
descriptionBundle,
|
||||
descriptionKey,
|
||||
Objects.toString(assetClass),
|
||||
data
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
package org.librecms.contentsection.rs;
|
||||
|
||||
import com.arsdigita.cms.ui.assets.AssetSearchWidget;
|
||||
import com.arsdigita.kernel.KernelConfig;
|
||||
|
||||
import org.libreccm.configuration.ConfigurationManager;
|
||||
|
|
@ -64,8 +63,7 @@ import javax.ws.rs.QueryParam;
|
|||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
/**
|
||||
* Provides a Web Service (build using JAX-RS). Used for example by the
|
||||
* {@link AssetSearchWidget}.
|
||||
* Provides a Web Service (build using JAX-RS).
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue