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 org.librecms.contentsection.ContentSection;
|
||||||
|
|
||||||
import com.arsdigita.cms.dispatcher.CMSPage;
|
import com.arsdigita.cms.dispatcher.CMSPage;
|
||||||
import com.arsdigita.cms.ui.assets.AssetPane;
|
|
||||||
import com.arsdigita.cms.ui.category.CategoryAdminPane;
|
import com.arsdigita.cms.ui.category.CategoryAdminPane;
|
||||||
//ToDo NG import com.arsdigita.cms.ui.category.CategoryAdminPane;
|
//ToDo NG import com.arsdigita.cms.ui.category.CategoryAdminPane;
|
||||||
import com.arsdigita.cms.ui.cse.ContentSoonExpiredPane;
|
import com.arsdigita.cms.ui.cse.ContentSoonExpiredPane;
|
||||||
|
|
@ -123,7 +122,7 @@ public class ContentSectionPage extends CMSPage implements ActionListener {
|
||||||
private FolderAdminPane m_folderPane;
|
private FolderAdminPane m_folderPane;
|
||||||
private BrowsePane m_browsePane;
|
private BrowsePane m_browsePane;
|
||||||
private ItemSearch m_searchPane;
|
private ItemSearch m_searchPane;
|
||||||
private AssetPane m_assetPane;
|
// private AssetPane m_assetPane;
|
||||||
//ToDo NG private ImagesPane m_imagesPane;
|
//ToDo NG private ImagesPane m_imagesPane;
|
||||||
private RoleAdminPane m_rolePane;
|
private RoleAdminPane m_rolePane;
|
||||||
private WorkflowAdminPane m_workflowPane;
|
private WorkflowAdminPane m_workflowPane;
|
||||||
|
|
@ -261,13 +260,13 @@ public class ContentSectionPage extends CMSPage implements ActionListener {
|
||||||
return m_searchPane;
|
return m_searchPane;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AssetPane getAssetPane() {
|
// protected AssetPane getAssetPane() {
|
||||||
if (m_assetPane == null) {
|
// if (m_assetPane == null) {
|
||||||
m_assetPane = new AssetPane();
|
// m_assetPane = new AssetPane();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
return m_assetPane;
|
// return m_assetPane;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// ToDo NG
|
// ToDo NG
|
||||||
// protected ImagesPane getImagesPane() {
|
// 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;
|
package org.librecms.assets;
|
||||||
|
|
||||||
import com.arsdigita.cms.ui.assets.AbstractAssetForm;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,6 @@
|
||||||
*/
|
*/
|
||||||
package org.librecms.assets;
|
package org.librecms.assets;
|
||||||
|
|
||||||
import com.arsdigita.cms.ui.assets.AbstractAssetForm;
|
|
||||||
|
|
||||||
import org.librecms.contentsection.Asset;
|
import org.librecms.contentsection.Asset;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
@ -56,11 +54,6 @@ public class AssetTypeInfo {
|
||||||
*/
|
*/
|
||||||
private Class<? extends Asset> assetClass;
|
private Class<? extends Asset> assetClass;
|
||||||
|
|
||||||
/**
|
|
||||||
* The form for editing and creating asset of the type described.
|
|
||||||
*/
|
|
||||||
private Class<? extends AbstractAssetForm> assetForm;
|
|
||||||
|
|
||||||
public String getLabelBundle() {
|
public String getLabelBundle() {
|
||||||
return labelBundle;
|
return labelBundle;
|
||||||
}
|
}
|
||||||
|
|
@ -101,14 +94,6 @@ public class AssetTypeInfo {
|
||||||
this.assetClass = assetClass;
|
this.assetClass = assetClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class<? extends AbstractAssetForm> getAssetForm() {
|
|
||||||
return assetForm;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAssetForm(final Class<? extends AbstractAssetForm> assetForm) {
|
|
||||||
this.assetForm = assetForm;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int hash = 5;
|
int hash = 5;
|
||||||
|
|
@ -117,7 +102,6 @@ public class AssetTypeInfo {
|
||||||
hash = 59 * hash + Objects.hashCode(descriptionBundle);
|
hash = 59 * hash + Objects.hashCode(descriptionBundle);
|
||||||
hash = 59 * hash + Objects.hashCode(descriptionKey);
|
hash = 59 * hash + Objects.hashCode(descriptionKey);
|
||||||
hash = 59 * hash + Objects.hashCode(assetClass);
|
hash = 59 * hash + Objects.hashCode(assetClass);
|
||||||
hash = 59 * hash + Objects.hashCode(assetForm);
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -148,10 +132,7 @@ public class AssetTypeInfo {
|
||||||
if (!Objects.equals(descriptionKey, other.getDescriptionKey())) {
|
if (!Objects.equals(descriptionKey, other.getDescriptionKey())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!Objects.equals(assetClass, other.getAssetClass())) {
|
return Objects.equals(assetClass, other.getAssetClass());
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return Objects.equals(assetForm, other.getAssetForm());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean canEqual(final Object obj) {
|
private boolean canEqual(final Object obj) {
|
||||||
|
|
@ -164,13 +145,13 @@ public class AssetTypeInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString(final String data) {
|
public String toString(final String data) {
|
||||||
return String.format("%s{ "
|
return String.format(
|
||||||
|
"%s{ "
|
||||||
+ "labelBundle = \"%s\", "
|
+ "labelBundle = \"%s\", "
|
||||||
+ "labelKey = \"%s\", "
|
+ "labelKey = \"%s\", "
|
||||||
+ "descriptionBundle = \"%s\", "
|
+ "descriptionBundle = \"%s\", "
|
||||||
+ "descriptionKey = \"%s\", "
|
+ "descriptionKey = \"%s\", "
|
||||||
+ "assetClass = \"%s\", "
|
+ "assetClass = \"%s\"%s "
|
||||||
+ "assetForm = \"%s\"%s "
|
|
||||||
+ " }",
|
+ " }",
|
||||||
super.toString(),
|
super.toString(),
|
||||||
labelBundle,
|
labelBundle,
|
||||||
|
|
@ -178,8 +159,8 @@ public class AssetTypeInfo {
|
||||||
descriptionBundle,
|
descriptionBundle,
|
||||||
descriptionKey,
|
descriptionKey,
|
||||||
Objects.toString(assetClass),
|
Objects.toString(assetClass),
|
||||||
Objects.toString(assetForm),
|
data
|
||||||
data);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@
|
||||||
*/
|
*/
|
||||||
package org.librecms.contentsection.rs;
|
package org.librecms.contentsection.rs;
|
||||||
|
|
||||||
import com.arsdigita.cms.ui.assets.AssetSearchWidget;
|
|
||||||
import com.arsdigita.kernel.KernelConfig;
|
import com.arsdigita.kernel.KernelConfig;
|
||||||
|
|
||||||
import org.libreccm.configuration.ConfigurationManager;
|
import org.libreccm.configuration.ConfigurationManager;
|
||||||
|
|
@ -64,8 +63,7 @@ import javax.ws.rs.QueryParam;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a Web Service (build using JAX-RS). Used for example by the
|
* Provides a Web Service (build using JAX-RS).
|
||||||
* {@link AssetSearchWidget}.
|
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue