CCM NG/ccm-cms: AssetFolderBrowser
git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4657 8810af33-2d31-482b-a856-94f89814c4dfccm-docs
parent
86c26c4600
commit
84437149fd
|
|
@ -36,6 +36,9 @@
|
|||
<Logger name="com.arsdigita.ui.admin.usersgroupsroles.UsersTable"
|
||||
level="debug">
|
||||
</Logger>
|
||||
<Logger name="com.arsdigita.cms.ui.assets.AssetPane"
|
||||
level="debug">
|
||||
</Logger>
|
||||
<Logger name="com.arsdigita.ui.login.UserLoginForm"
|
||||
level="debug">
|
||||
</Logger>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
package com.arsdigita.cms.ui.assets;
|
||||
|
||||
import com.arsdigita.cms.ui.folder.FolderBrowser;
|
||||
import com.arsdigita.kernel.KernelConfig;
|
||||
|
||||
import org.libreccm.categorization.Category;
|
||||
|
|
@ -29,13 +28,10 @@ import org.librecms.CmsConstants;
|
|||
import org.librecms.assets.AssetTypeInfo;
|
||||
import org.librecms.assets.AssetTypesManager;
|
||||
import org.librecms.contentsection.Asset;
|
||||
import org.librecms.contentsection.ContentType;
|
||||
|
||||
import org.librecms.contentsection.Folder;
|
||||
import org.librecms.contenttypes.ContentTypeInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
|
@ -53,10 +49,18 @@ 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 static org.librecms.CmsConstants.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
|
|
@ -79,9 +83,15 @@ public class AssetFolderBrowserController {
|
|||
@Inject
|
||||
private FolderRepository folderRepo;
|
||||
|
||||
@Inject
|
||||
private FolderManager folderManager;
|
||||
|
||||
@Inject
|
||||
private AssetRepository assetRepo;
|
||||
|
||||
@Inject
|
||||
private AssetManager assetManager;
|
||||
|
||||
@Inject
|
||||
private GlobalizationHelper globalizationHelper;
|
||||
|
||||
|
|
@ -107,6 +117,7 @@ public class AssetFolderBrowserController {
|
|||
final int firstResult,
|
||||
final int maxResults) {
|
||||
final List<Folder> subFolders = findSubFolders(folder,
|
||||
"%",
|
||||
orderBy,
|
||||
orderDirection,
|
||||
firstResult,
|
||||
|
|
@ -123,6 +134,7 @@ public class AssetFolderBrowserController {
|
|||
final int firstAsset = firstResult - subFolders.size();
|
||||
|
||||
final List<Asset> assets = findAssetsInFolder(folder,
|
||||
"%",
|
||||
orderBy,
|
||||
orderDirection,
|
||||
firstAsset,
|
||||
|
|
@ -143,7 +155,15 @@ public class AssetFolderBrowserController {
|
|||
@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);
|
||||
|
|
@ -153,12 +173,14 @@ public class AssetFolderBrowserController {
|
|||
|
||||
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,
|
||||
|
|
@ -180,6 +202,218 @@ public class AssetFolderBrowserController {
|
|||
|
||||
}
|
||||
|
||||
@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_ITEM.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.
|
||||
*
|
||||
|
|
@ -252,10 +486,13 @@ public class AssetFolderBrowserController {
|
|||
|
||||
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,
|
||||
|
|
@ -279,8 +516,12 @@ public class AssetFolderBrowserController {
|
|||
final TypedQuery<Folder> query = entityManager
|
||||
.createQuery(
|
||||
criteria.where(
|
||||
builder.
|
||||
equal(from.get("parentCategory"), folder)
|
||||
builder.and(
|
||||
builder.equal(from.get("parentCategory"),
|
||||
folder),
|
||||
builder.like(builder.lower(from.get("name")),
|
||||
filterTerm)
|
||||
)
|
||||
)
|
||||
.orderBy(order)
|
||||
);
|
||||
|
|
@ -297,6 +538,7 @@ public class AssetFolderBrowserController {
|
|||
}
|
||||
|
||||
private List<Asset> findAssetsInFolder(final Folder folder,
|
||||
final String filterTerm,
|
||||
final String orderBy,
|
||||
final String orderDirection,
|
||||
final int firstResult,
|
||||
|
|
@ -339,7 +581,10 @@ public class AssetFolderBrowserController {
|
|||
builder.equal(join.get(
|
||||
"category"), folder),
|
||||
builder.equal(join.get("type"),
|
||||
CmsConstants.CATEGORIZATION_TYPE_FOLDER)
|
||||
CmsConstants.CATEGORIZATION_TYPE_FOLDER),
|
||||
builder.like(builder.lower(fromAsset.get(
|
||||
"displayName")),
|
||||
filterTerm)
|
||||
)
|
||||
)
|
||||
.orderBy(order)
|
||||
|
|
|
|||
|
|
@ -19,27 +19,35 @@
|
|||
package com.arsdigita.cms.ui.assets;
|
||||
|
||||
import com.arsdigita.bebop.ActionLink;
|
||||
import com.arsdigita.bebop.BoxPanel;
|
||||
import com.arsdigita.bebop.Component;
|
||||
import com.arsdigita.bebop.ControlLink;
|
||||
import com.arsdigita.bebop.Form;
|
||||
import com.arsdigita.bebop.FormData;
|
||||
import com.arsdigita.bebop.FormProcessException;
|
||||
import com.arsdigita.bebop.Label;
|
||||
import com.arsdigita.bebop.Page;
|
||||
import com.arsdigita.bebop.PageState;
|
||||
import com.arsdigita.bebop.Paginator;
|
||||
import com.arsdigita.bebop.RequestLocal;
|
||||
import com.arsdigita.bebop.Resettable;
|
||||
import com.arsdigita.bebop.SaveCancelSection;
|
||||
import com.arsdigita.bebop.SegmentedPanel;
|
||||
import com.arsdigita.bebop.SimpleContainer;
|
||||
import com.arsdigita.bebop.SingleSelectionModel;
|
||||
import com.arsdigita.bebop.Table;
|
||||
import com.arsdigita.bebop.Text;
|
||||
import com.arsdigita.bebop.Tree;
|
||||
import com.arsdigita.bebop.event.ActionEvent;
|
||||
import com.arsdigita.bebop.event.ActionListener;
|
||||
import com.arsdigita.bebop.event.FormProcessListener;
|
||||
import com.arsdigita.bebop.event.FormSectionEvent;
|
||||
import com.arsdigita.bebop.event.FormSubmissionListener;
|
||||
import com.arsdigita.bebop.event.FormValidationListener;
|
||||
import com.arsdigita.bebop.event.PrintEvent;
|
||||
import com.arsdigita.bebop.event.PrintListener;
|
||||
import com.arsdigita.bebop.form.CheckboxGroup;
|
||||
import com.arsdigita.bebop.form.FormErrorDisplay;
|
||||
import com.arsdigita.bebop.form.Option;
|
||||
import com.arsdigita.bebop.form.SingleSelect;
|
||||
import com.arsdigita.bebop.form.Submit;
|
||||
|
|
@ -47,6 +55,7 @@ import com.arsdigita.bebop.parameters.ArrayParameter;
|
|||
import com.arsdigita.bebop.parameters.StringParameter;
|
||||
import com.arsdigita.bebop.table.TableCellRenderer;
|
||||
import com.arsdigita.bebop.table.TableColumn;
|
||||
import com.arsdigita.bebop.tree.TreeCellRenderer;
|
||||
import com.arsdigita.cms.CMS;
|
||||
import com.arsdigita.cms.ui.BaseTree;
|
||||
import com.arsdigita.cms.ui.folder.FolderCreateForm;
|
||||
|
|
@ -59,6 +68,8 @@ import com.arsdigita.globalization.GlobalizedMessage;
|
|||
import com.arsdigita.toolbox.ui.ActionGroup;
|
||||
import com.arsdigita.toolbox.ui.LayoutPanel;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.libreccm.categorization.Category;
|
||||
import org.libreccm.cdi.utils.CdiUtil;
|
||||
import org.librecms.CmsConstants;
|
||||
|
|
@ -68,8 +79,21 @@ import org.librecms.contentsection.Folder;
|
|||
import java.util.List;
|
||||
|
||||
import org.arsdigita.cms.CMSConfig;
|
||||
import org.libreccm.categorization.CategoryManager;
|
||||
import org.libreccm.core.CcmObject;
|
||||
import org.libreccm.core.UnexpectedErrorException;
|
||||
import org.libreccm.security.PermissionChecker;
|
||||
import org.librecms.contentsection.Asset;
|
||||
import org.librecms.contentsection.AssetManager;
|
||||
import org.librecms.contentsection.AssetRepository;
|
||||
import org.librecms.contentsection.FolderManager;
|
||||
import org.librecms.contentsection.FolderRepository;
|
||||
import org.librecms.contentsection.privileges.ItemPrivileges;
|
||||
|
||||
import javax.swing.CellRendererPane;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.librecms.CmsConstants.*;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -77,6 +101,8 @@ import javax.swing.CellRendererPane;
|
|||
*/
|
||||
public class AssetPane extends LayoutPanel implements Resettable {
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger(AssetPane.class);
|
||||
|
||||
public static final String SET_FOLDER = "set_folder";
|
||||
private static final String SOURCES_PARAM = "sources";
|
||||
private static final String ACTION_PARAM = "action";
|
||||
|
|
@ -89,10 +115,14 @@ public class AssetPane extends LayoutPanel implements Resettable {
|
|||
private final FolderRequestLocal folderRequestLocal;
|
||||
private final ArrayParameter sourcesParameter = new ArrayParameter(
|
||||
new StringParameter(SOURCES_PARAM));
|
||||
private final StringParameter actionParameter = new StringParameter(
|
||||
ACTION_PARAM);
|
||||
|
||||
private AssetFolderBrowser folderBrowser;
|
||||
private Form browserForm;
|
||||
private SingleSelect actionSelect;
|
||||
private Submit actionSubmit;
|
||||
private TargetSelector targetSelector;
|
||||
|
||||
private SegmentedPanel.Segment browseSegment;
|
||||
private SegmentedPanel.Segment currentFolderSegment;
|
||||
|
|
@ -145,7 +175,7 @@ public class AssetPane extends LayoutPanel implements Resettable {
|
|||
final SegmentedPanel panel = new SegmentedPanel();
|
||||
|
||||
browseSegment = panel.addSegment();
|
||||
final Form browserForm = new Form("assetFolderBrowser",
|
||||
browserForm = new Form("assetFolderBrowser",
|
||||
new SimpleContainer());
|
||||
browserForm.setMethod(Form.GET);
|
||||
folderBrowser = new AssetFolderBrowser(folderSelectionModel);
|
||||
|
|
@ -186,7 +216,7 @@ public class AssetPane extends LayoutPanel implements Resettable {
|
|||
new GlobalizedMessage(
|
||||
"cms.ui.folder.edit_selection",
|
||||
CmsConstants.CMS_FOLDER_BUNDLE)));
|
||||
actionSelect = new SingleSelect(ACTION_PARAM);
|
||||
actionSelect = new SingleSelect(actionParameter);
|
||||
actionSelect.addOption(
|
||||
new Option(COPY,
|
||||
new Label(new GlobalizedMessage(
|
||||
|
|
@ -203,8 +233,68 @@ public class AssetPane extends LayoutPanel implements Resettable {
|
|||
new GlobalizedMessage("cms.ui.folder.go",
|
||||
CmsConstants.CMS_FOLDER_BUNDLE));
|
||||
actionFormContainer.add(actionSubmit);
|
||||
browserForm.addProcessListener(new FormProcessListener() {
|
||||
|
||||
@Override
|
||||
public void process(final FormSectionEvent event)
|
||||
throws FormProcessException {
|
||||
|
||||
final PageState state = event.getPageState();
|
||||
|
||||
moveCopyMode(state);
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
browserForm.add(actionFormContainer);
|
||||
|
||||
targetSelector = new TargetSelector();
|
||||
targetSelector.addProcessListener(new FormProcessListener() {
|
||||
|
||||
@Override
|
||||
public void process(final FormSectionEvent event)
|
||||
throws FormProcessException {
|
||||
|
||||
final PageState state = event.getPageState();
|
||||
|
||||
browseMode(state);
|
||||
targetSelector.setVisible(state, false);
|
||||
|
||||
final Folder folder = targetSelector.getTarget(state);
|
||||
final String[] objectIds = getSources(state);
|
||||
|
||||
if (isCopy(state)) {
|
||||
copyObjects(folder, objectIds);
|
||||
} else if (isMove(state)) {
|
||||
moveObjects(folder, objectIds);
|
||||
}
|
||||
|
||||
reset(state);
|
||||
}
|
||||
|
||||
});
|
||||
targetSelector.addValidationListener(
|
||||
new TargetSelectorValidationListener());
|
||||
targetSelector.addSubmissionListener(new FormSubmissionListener() {
|
||||
|
||||
@Override
|
||||
public void submitted(final FormSectionEvent event)
|
||||
throws FormProcessException {
|
||||
|
||||
final PageState state = event.getPageState();
|
||||
|
||||
if (targetSelector.isCancelled(state)) {
|
||||
reset(state);
|
||||
browseMode(state);
|
||||
throw new FormProcessException(new GlobalizedMessage(
|
||||
"cms.ui.folder.cancelled",
|
||||
CmsConstants.CMS_FOLDER_BUNDLE));
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
browseSegment.add(targetSelector);
|
||||
|
||||
// browseSegment.add(paginator);
|
||||
// browseSegment.add(folderBrowser);
|
||||
browseSegment.add(browserForm);
|
||||
|
|
@ -352,22 +442,44 @@ public class AssetPane extends LayoutPanel implements Resettable {
|
|||
}
|
||||
|
||||
protected void browseMode(final PageState state) {
|
||||
tree.setVisible(state, true);
|
||||
browseSegment.setVisible(state, true);
|
||||
folderBrowser.setVisible(state, true);
|
||||
browserForm.setVisible(state, true);
|
||||
targetSelector.setVisible(state, false);
|
||||
actionsSegment.setVisible(state, true);
|
||||
newFolderSegment.setVisible(state, false);
|
||||
editFolderSegment.setVisible(state, false);
|
||||
|
||||
}
|
||||
|
||||
protected void moveCopyMode(final PageState state) {
|
||||
tree.setVisible(state, false);
|
||||
browseSegment.setVisible(state, true);
|
||||
folderBrowser.setVisible(state, false);
|
||||
browserForm.setVisible(state, false);
|
||||
targetSelector.setVisible(state, true);
|
||||
actionsSegment.setVisible(state, false);
|
||||
newFolderSegment.setVisible(state, false);
|
||||
editFolderSegment.setVisible(state, false);
|
||||
targetSelector.expose(state);
|
||||
}
|
||||
|
||||
protected void newFolderMode(final PageState state) {
|
||||
tree.setVisible(state, false);
|
||||
browseSegment.setVisible(state, false);
|
||||
folderBrowser.setVisible(state, false);
|
||||
browserForm.setVisible(state, false);
|
||||
targetSelector.setVisible(state, false);
|
||||
actionsSegment.setVisible(state, false);
|
||||
newFolderSegment.setVisible(state, true);
|
||||
editFolderSegment.setVisible(state, false);
|
||||
}
|
||||
|
||||
protected void editFolderMode(final PageState state) {
|
||||
tree.setVisible(state, false);
|
||||
browseSegment.setVisible(state, false);
|
||||
targetSelector.setVisible(state, false);
|
||||
actionsSegment.setVisible(state, false);
|
||||
newFolderSegment.setVisible(state, false);
|
||||
editFolderSegment.setVisible(state, true);
|
||||
|
|
@ -381,10 +493,17 @@ public class AssetPane extends LayoutPanel implements Resettable {
|
|||
page.addActionListener(new TreeListener());
|
||||
page.addActionListener(new FolderListener());
|
||||
|
||||
page.setVisibleDefault(tree, true);
|
||||
page.setVisibleDefault(browseSegment, true);
|
||||
page.setVisibleDefault(folderBrowser, true);
|
||||
page.setVisibleDefault(browserForm, true);
|
||||
page.setVisibleDefault(targetSelector, false);
|
||||
page.setVisibleDefault(actionsSegment, true);
|
||||
page.setVisibleDefault(newFolderSegment, false);
|
||||
page.setVisibleDefault(editFolderSegment, false);
|
||||
|
||||
page.addComponentStateParam(this, actionParameter);
|
||||
page.addComponentStateParam(this, sourcesParameter);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -394,6 +513,50 @@ public class AssetPane extends LayoutPanel implements Resettable {
|
|||
|
||||
folderBrowser.getPaginator().reset(state);
|
||||
|
||||
state.setValue(actionParameter, null);
|
||||
state.setValue(sourcesParameter, null);
|
||||
|
||||
}
|
||||
|
||||
private String[] getSources(final PageState state) {
|
||||
|
||||
final String[] result = (String[]) state.getValue(sourcesParameter);
|
||||
|
||||
if (result == null) {
|
||||
return new String[0];
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
protected final boolean isMove(final PageState state) {
|
||||
return MOVE.equals(getAction(state));
|
||||
}
|
||||
|
||||
protected final boolean isCopy(final PageState state) {
|
||||
return COPY.equals(getAction(state));
|
||||
}
|
||||
|
||||
private String getAction(final PageState state) {
|
||||
return (String) state.getValue(actionParameter);
|
||||
}
|
||||
|
||||
protected void moveObjects(final Folder target, final String[] objectIds) {
|
||||
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final AssetFolderBrowserController controller = cdiUtil.findBean(
|
||||
AssetFolderBrowserController.class);
|
||||
|
||||
controller.moveObjects(target, objectIds);
|
||||
}
|
||||
|
||||
protected void copyObjects(final Folder target, final String[] objectIds) {
|
||||
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final AssetFolderBrowserController controller = cdiUtil.findBean(
|
||||
AssetFolderBrowserController.class);
|
||||
|
||||
controller.copyObjects(target, objectIds);
|
||||
}
|
||||
|
||||
private final class FolderListener implements ActionListener {
|
||||
|
|
@ -452,4 +615,385 @@ public class AssetPane extends LayoutPanel implements Resettable {
|
|||
|
||||
}
|
||||
|
||||
private class TargetSelector extends Form implements Resettable {
|
||||
|
||||
private final FolderSelectionModel targetFolderModel;
|
||||
private final AssetFolderTree folderTree;
|
||||
private final Submit cancelButton;
|
||||
|
||||
public TargetSelector() {
|
||||
super("targetSelector", new BoxPanel());
|
||||
setMethod(GET);
|
||||
targetFolderModel = new FolderSelectionModel("target") {
|
||||
|
||||
@Override
|
||||
protected Long getRootFolderID(final PageState state) {
|
||||
final ContentSection section = CMS
|
||||
.getContext()
|
||||
.getContentSection();
|
||||
return section.getRootAssetsFolder().getObjectId();
|
||||
}
|
||||
|
||||
};
|
||||
folderTree = new AssetFolderTree(targetFolderModel);
|
||||
|
||||
folderTree.setCellRenderer(new FolderTreeCellRenderer());
|
||||
|
||||
final Label label = new Label(new PrintListener() {
|
||||
|
||||
@Override
|
||||
public void prepare(final PrintEvent event) {
|
||||
|
||||
final PageState state = event.getPageState();
|
||||
final Label label = (Label) event.getTarget();
|
||||
final int numberOfItems = getSources(state).length;
|
||||
final Category folder = (Category) folderSelectionModel
|
||||
.getSelectedObject(state);
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final CategoryManager categoryManager = cdiUtil
|
||||
.findBean(CategoryManager.class);
|
||||
|
||||
if (isMove(state)) {
|
||||
label.setLabel(new GlobalizedMessage(
|
||||
"cms.ui.folder.move",
|
||||
CmsConstants.CMS_FOLDER_BUNDLE,
|
||||
new Object[]{numberOfItems,
|
||||
categoryManager.getCategoryPath(folder)}));
|
||||
} else if (isCopy(state)) {
|
||||
label.setLabel(new GlobalizedMessage(
|
||||
"cms.ui.folder.copy",
|
||||
CMS_BUNDLE,
|
||||
new Object[]{numberOfItems,
|
||||
categoryManager.getCategoryPath(
|
||||
folder)}));
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
label.setOutputEscaping(false);
|
||||
add(label);
|
||||
add(folderTree);
|
||||
add(new FormErrorDisplay(this));
|
||||
final SaveCancelSection saveCancelSection = new SaveCancelSection();
|
||||
cancelButton = saveCancelSection.getCancelButton();
|
||||
add(saveCancelSection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(final Page page) {
|
||||
super.register(page);
|
||||
page.addComponentStateParam(this, targetFolderModel
|
||||
.getStateParameter());
|
||||
}
|
||||
|
||||
public void expose(final PageState state) {
|
||||
|
||||
final Folder folder = folderSelectionModel.getSelectedObject(state);
|
||||
targetFolderModel.clearSelection(state);
|
||||
if (folder != null) {
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final FolderManager folderManager = cdiUtil.findBean(
|
||||
FolderManager.class);
|
||||
if (!folderManager.getParentFolder(folder).isPresent()) {
|
||||
folderTree.expand(Long.toString(folder.getObjectId()),
|
||||
state);
|
||||
} else {
|
||||
final List<Folder> parents = folderManager
|
||||
.getParentFolders(folder);
|
||||
parents
|
||||
.stream()
|
||||
.map(parent -> Long.toString(parent.getObjectId()))
|
||||
.forEach(folderId -> folderTree.expand(folderId, state));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(final PageState state) {
|
||||
folderTree.clearSelection(state);
|
||||
state.setValue(folderTree.getSelectionModel().getStateParameter(),
|
||||
null);
|
||||
}
|
||||
|
||||
public Folder getTarget(final PageState state) {
|
||||
return targetFolderModel.getSelectedObject(state);
|
||||
}
|
||||
|
||||
public boolean isCancelled(final PageState state) {
|
||||
return cancelButton.isSelected(state);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class FolderTreeCellRenderer implements TreeCellRenderer {
|
||||
|
||||
private final RequestLocal invalidFoldersRequestLocal
|
||||
= new RequestLocal();
|
||||
|
||||
/**
|
||||
* Render the folders appropriately. The selected folder is a bold
|
||||
* label. Invalid folders are plain labels. Unselected, valid folders
|
||||
* are control links. Invalid folders are: the parent folder of the
|
||||
* sources, any of the sources, and any subfolders of the sources.
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Component getComponent(final Tree tree,
|
||||
final PageState state,
|
||||
final Object value,
|
||||
final boolean isSelected,
|
||||
final boolean isExpanded,
|
||||
final boolean isLeaf,
|
||||
final Object key) {
|
||||
|
||||
// Get the list of invalid folders once per request.
|
||||
final List<String> invalidFolders;
|
||||
|
||||
if (invalidFoldersRequestLocal.get(state) == null) {
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final AssetFolderBrowserController controller = cdiUtil
|
||||
.findBean(AssetFolderBrowserController.class);
|
||||
invalidFolders = controller.createInvalidTargetsList(
|
||||
Arrays.asList(getSources(state)));
|
||||
invalidFoldersRequestLocal.set(state, invalidFolders);
|
||||
} else {
|
||||
invalidFolders = (List<String>) invalidFoldersRequestLocal
|
||||
.get(state);
|
||||
}
|
||||
final Label label = new Label(value.toString());
|
||||
|
||||
if (invalidFolders.contains(String.format(
|
||||
FOLDER_BROWSER_KEY_PREFIX_FOLDER + "%s", key))) {
|
||||
return label;
|
||||
}
|
||||
|
||||
// Bold if selected
|
||||
if (isSelected) {
|
||||
label.setFontWeight(Label.BOLD);
|
||||
return label;
|
||||
}
|
||||
|
||||
return new ControlLink(label);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class TargetSelectorValidationListener
|
||||
implements FormValidationListener {
|
||||
|
||||
@Override
|
||||
public void validate(final FormSectionEvent event)
|
||||
throws FormProcessException {
|
||||
|
||||
final PageState state = event.getPageState();
|
||||
|
||||
if (getSources(state).length <= 0) {
|
||||
throw new IllegalStateException("No source items specified");
|
||||
}
|
||||
|
||||
final Folder target = targetSelector.getTarget(state);
|
||||
final FormData data = event.getFormData();
|
||||
if (target == null) {
|
||||
data.addError(new GlobalizedMessage(
|
||||
"cms.ui.folder.need_select_target_folder",
|
||||
CmsConstants.CMS_FOLDER_BUNDLE));
|
||||
//If the target is null, we can skip the rest of the checks
|
||||
return;
|
||||
}
|
||||
|
||||
if (target.equals(folderSelectionModel.getSelectedObject(state))) {
|
||||
data.addError(new GlobalizedMessage(
|
||||
"cms.ui.folder.not_within_same_folder",
|
||||
CmsConstants.CMS_FOLDER_BUNDLE));
|
||||
}
|
||||
|
||||
// check create item permission
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final PermissionChecker permissionChecker = cdiUtil.findBean(
|
||||
PermissionChecker.class);
|
||||
if (!permissionChecker.isPermitted(
|
||||
ItemPrivileges.CREATE_NEW, target)) {
|
||||
data.addError("cms.ui.folder.no_permission_for_item",
|
||||
CmsConstants.CMS_FOLDER_BUNDLE);
|
||||
}
|
||||
|
||||
for (String source : getSources(state)) {
|
||||
|
||||
validateObject(source, target, state, data);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void validateObject(final String objectId,
|
||||
final Folder target,
|
||||
final PageState state,
|
||||
final FormData data) {
|
||||
|
||||
Objects.requireNonNull(objectId, "objectId can't be null.");
|
||||
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final FolderRepository folderRepo = cdiUtil
|
||||
.findBean(FolderRepository.class);
|
||||
final AssetRepository assetRepo = cdiUtil
|
||||
.findBean(AssetRepository.class);
|
||||
final AssetManager assetManager = cdiUtil
|
||||
.findBean(AssetManager.class);
|
||||
final AssetFolderBrowserController controller = cdiUtil
|
||||
.findBean(AssetFolderBrowserController.class);
|
||||
final FolderManager folderManager = cdiUtil
|
||||
.findBean(FolderManager.class);
|
||||
final PermissionChecker permissionChecker = cdiUtil.findBean(
|
||||
PermissionChecker.class);
|
||||
|
||||
final CcmObject object;
|
||||
final String name;
|
||||
if (objectId.startsWith(FOLDER_BROWSER_KEY_PREFIX_FOLDER)) {
|
||||
|
||||
final long folderId = Long.parseLong(objectId.substring(
|
||||
FOLDER_BROWSER_KEY_PREFIX_FOLDER.length()));
|
||||
final Folder folder = folderRepo.findById(folderId).orElseThrow(
|
||||
() -> new IllegalArgumentException(String.format(
|
||||
"No folder with id %d in database.", folderId)));
|
||||
|
||||
name = folder.getName();
|
||||
|
||||
//Check if folder or subfolder contains in use assets
|
||||
if (isMove(state)) {
|
||||
final FolderManager.FolderIsMovable movable = folderManager
|
||||
.folderIsMovable(folder, target);
|
||||
switch (movable) {
|
||||
case DIFFERENT_SECTIONS:
|
||||
addErrorMessage(data,
|
||||
"cms.ui.folder.different_sections",
|
||||
name);
|
||||
break;
|
||||
case HAS_IN_USE_ASSETS:
|
||||
addErrorMessage(data,
|
||||
"cms.ui.folder.has_in_use_assets",
|
||||
name);
|
||||
break;
|
||||
case DIFFERENT_TYPES:
|
||||
addErrorMessage(data,
|
||||
"cms.ui.folder.different_folder_types",
|
||||
name);
|
||||
break;
|
||||
case IS_ROOT_FOLDER:
|
||||
addErrorMessage(data,
|
||||
"cms.ui.folder.is_root_folder",
|
||||
name);
|
||||
break;
|
||||
case SAME_FOLDER:
|
||||
addErrorMessage(data,
|
||||
"cms.ui.folder.same_folder",
|
||||
name);
|
||||
break;
|
||||
case YES:
|
||||
//Nothing
|
||||
break;
|
||||
default:
|
||||
throw new UnexpectedErrorException(String.format(
|
||||
"Unknown state '%s' for '%s'.",
|
||||
movable,
|
||||
FolderManager.FolderIsMovable.class.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
object = folder;
|
||||
} else if (objectId.startsWith(FOLDER_BROWSER_KEY_PREFIX_ASSET)) {
|
||||
final long assetId = Long.parseLong(objectId.substring(
|
||||
FOLDER_BROWSER_KEY_PREFIX_ASSET.length()));
|
||||
final Asset asset = assetRepo
|
||||
.findById(assetId)
|
||||
.orElseThrow(() -> new IllegalArgumentException(
|
||||
String.format(
|
||||
"No asset with id %d in the database.",
|
||||
assetId)));
|
||||
|
||||
name = asset.getDisplayName();
|
||||
|
||||
if (isMove(state) && assetManager.isAssetInUse(asset)) {
|
||||
addErrorMessage(data, "cms.ui.folder.item_is_live", name);
|
||||
}
|
||||
|
||||
object = asset;
|
||||
} else {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Provided objectId '%s' does not start with '%s' "
|
||||
+ "or '%s'.",
|
||||
objectId,
|
||||
FOLDER_BROWSER_KEY_PREFIX_FOLDER,
|
||||
FOLDER_BROWSER_KEY_PREFIX_ASSET));
|
||||
}
|
||||
|
||||
final long count = controller.countObjects(target, name);
|
||||
if (count > 0) {
|
||||
// there is an item or subfolder in the target folder that already has this name
|
||||
addErrorMessage(data, "cms.ui.folder.item_already_exists",
|
||||
name);
|
||||
}
|
||||
|
||||
if (!(permissionChecker.isPermitted(
|
||||
ItemPrivileges.DELETE, object))
|
||||
&& isMove(state)) {
|
||||
addErrorMessage(data,
|
||||
"cms.ui.folder.no_permission_for_item",
|
||||
object.getDisplayName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void addErrorMessage(final FormData data,
|
||||
final String message,
|
||||
final String itemName) {
|
||||
data.addError(new GlobalizedMessage(message,
|
||||
CmsConstants.CMS_FOLDER_BUNDLE,
|
||||
new Object[]{itemName}));
|
||||
}
|
||||
|
||||
private class AssetFolderTree extends Tree {
|
||||
|
||||
public AssetFolderTree(final FolderSelectionModel folderSelectionModel) {
|
||||
|
||||
super(new FolderTreeModelBuilder() {
|
||||
|
||||
@Override
|
||||
protected Folder getRootFolder(final PageState state) {
|
||||
final ContentSection section = CMS
|
||||
.getContext()
|
||||
.getContentSection();
|
||||
|
||||
return section.getRootAssetsFolder();
|
||||
}
|
||||
|
||||
});
|
||||
setSelectionModel(selectionModel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelectedKey(final PageState state, final Object key) {
|
||||
if (key instanceof String) {
|
||||
final Long keyAsLong;
|
||||
if (((String) key).startsWith(
|
||||
FOLDER_BROWSER_KEY_PREFIX_FOLDER)) {
|
||||
keyAsLong = Long.parseLong(((String) key).substring(
|
||||
FOLDER_BROWSER_KEY_PREFIX_FOLDER.length()));
|
||||
} else {
|
||||
keyAsLong = Long.parseLong((String) key);
|
||||
}
|
||||
super.setSelectedKey(state, keyAsLong);
|
||||
} else if (key instanceof Long) {
|
||||
super.setSelectedKey(state, key);
|
||||
} else {
|
||||
//We know that a FolderSelectionModel only takes keys of type Long.
|
||||
//Therefore we try to cast here
|
||||
final Long keyAsLong = (Long) key;
|
||||
super.setSelectedKey(state, keyAsLong);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -573,7 +573,7 @@ public class FolderBrowserController {
|
|||
CmsConstants.CATEGORIZATION_TYPE_FOLDER),
|
||||
builder.equal(fromItem.get("version"),
|
||||
ContentItemVersion.DRAFT),
|
||||
builder.like(fromItem.get("displayName"),
|
||||
builder.like(builder.lower(fromItem.get("displayName")),
|
||||
filterTerm)
|
||||
)
|
||||
)
|
||||
|
|
@ -780,7 +780,8 @@ public class FolderBrowserController {
|
|||
|
||||
Objects.requireNonNull(targetFolder);
|
||||
|
||||
final ContentItem item = itemRepo.findById(itemId)
|
||||
final ContentItem item = itemRepo
|
||||
.findById(itemId)
|
||||
.orElseThrow(() -> new IllegalArgumentException(String.format(
|
||||
"No content item with ID %d in the database. "
|
||||
+ "Where did that ID come from?",
|
||||
|
|
@ -834,7 +835,8 @@ public class FolderBrowserController {
|
|||
|
||||
Objects.requireNonNull(targetFolder);
|
||||
|
||||
final ContentItem item = itemRepo.findById(itemId)
|
||||
final ContentItem item = itemRepo
|
||||
.findById(itemId)
|
||||
.orElseThrow(() -> new IllegalArgumentException(String.format(
|
||||
"No content item with ID %d in the database. "
|
||||
+ "Where did that ID come from?",
|
||||
|
|
|
|||
|
|
@ -414,8 +414,8 @@ public class FolderManipulator extends SimpleContainer implements
|
|||
}
|
||||
|
||||
@Override
|
||||
public void process(final FormSectionEvent event) throws
|
||||
FormProcessException {
|
||||
public void process(final FormSectionEvent event)
|
||||
throws FormProcessException {
|
||||
|
||||
final PageState state = event.getPageState();
|
||||
|
||||
|
|
@ -484,16 +484,16 @@ public class FolderManipulator extends SimpleContainer implements
|
|||
|
||||
}
|
||||
|
||||
private class TargetSelectorValidationListener implements
|
||||
FormValidationListener {
|
||||
private class TargetSelectorValidationListener
|
||||
implements FormValidationListener {
|
||||
|
||||
public TargetSelectorValidationListener() {
|
||||
//Nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(final FormSectionEvent event) throws
|
||||
FormProcessException {
|
||||
public void validate(final FormSectionEvent event)
|
||||
throws FormProcessException {
|
||||
|
||||
final PageState state = event.getPageState();
|
||||
|
||||
|
|
@ -519,7 +519,6 @@ public class FolderManipulator extends SimpleContainer implements
|
|||
|
||||
// check create item permission
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final Shiro shiro = cdiUtil.findBean(Shiro.class);
|
||||
final PermissionChecker permissionChecker = cdiUtil.findBean(
|
||||
PermissionChecker.class);
|
||||
if (!permissionChecker.isPermitted(
|
||||
|
|
@ -614,8 +613,10 @@ public class FolderManipulator extends SimpleContainer implements
|
|||
} else if (objectId.startsWith(FOLDER_BROWSER_KEY_PREFIX_ITEM)) {
|
||||
final long itemId = Long.parseLong(objectId.substring(
|
||||
FOLDER_BROWSER_KEY_PREFIX_ITEM.length()));
|
||||
final ContentItem item = itemRepo.findById(itemId).orElseThrow(
|
||||
() -> new IllegalArgumentException(String.format(
|
||||
final ContentItem item = itemRepo
|
||||
.findById(itemId)
|
||||
.orElseThrow(() -> new IllegalArgumentException(
|
||||
String.format(
|
||||
"No content item with id %d in database.",
|
||||
itemId)));
|
||||
|
||||
|
|
@ -742,8 +743,8 @@ public class FolderManipulator extends SimpleContainer implements
|
|||
final PageState state = event.getPageState();
|
||||
final Label label = (Label) event.getTarget();
|
||||
final int numberOfItems = getSources(state).length;
|
||||
final Category folder = (Category) sourceFolderModel.
|
||||
getSelectedObject(state);
|
||||
final Category folder = (Category) sourceFolderModel
|
||||
.getSelectedObject(state);
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final CategoryManager categoryManager = cdiUtil.
|
||||
findBean(CategoryManager.class);
|
||||
|
|
@ -795,9 +796,10 @@ public class FolderManipulator extends SimpleContainer implements
|
|||
folderTree.expand(Long.toString(folder.getObjectId()),
|
||||
state);
|
||||
} else {
|
||||
final List<Folder> parents = folderManager.getParentFolders(
|
||||
folder);
|
||||
parents.stream()
|
||||
final List<Folder> parents = folderManager
|
||||
.getParentFolders(folder);
|
||||
parents
|
||||
.stream()
|
||||
.map(parent -> Long.toString(parent.getObjectId()))
|
||||
.forEach(folderId -> folderTree.expand(folderId, state));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ public class FolderTree extends Tree {
|
|||
} else if (key instanceof Long) {
|
||||
super.setSelectedKey(state, key);
|
||||
} else {
|
||||
//We now that a FolderSelectionModel only takes keys of type Long.
|
||||
//We know that a FolderSelectionModel only takes keys of type Long.
|
||||
//Therefore we try to cast here
|
||||
final Long keyAsLong = (Long) key;
|
||||
super.setSelectedKey(state, keyAsLong);
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ public class CmsConstants {
|
|||
public static final String CATEGORIZATION_TYPE_FOLDER = "folder";
|
||||
|
||||
public static final String FOLDER_BROWSER_KEY_PREFIX_FOLDER = "folder-";
|
||||
public static final String FOLDER_BROWSER_KEY_PREFIX_ASSET = "asset-";
|
||||
public static final String FOLDER_BROWSER_KEY_PREFIX_ITEM = "item-";
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -66,6 +66,9 @@ public class FolderManager {
|
|||
@Inject
|
||||
private ContentItemManager itemManager;
|
||||
|
||||
@Inject
|
||||
private AssetManager assetManager;
|
||||
|
||||
/**
|
||||
* An enum describing if a folder can be deleted or not and why.
|
||||
*
|
||||
|
|
@ -118,7 +121,11 @@ public class FolderManager {
|
|||
/**
|
||||
* The folder to move contains live items.
|
||||
*/
|
||||
HAS_LIVE_ITEMS
|
||||
HAS_LIVE_ITEMS,
|
||||
/**
|
||||
* The folder to contains assets which are in use.
|
||||
*/
|
||||
HAS_IN_USE_ASSETS
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
|
|
@ -368,6 +375,10 @@ public class FolderManager {
|
|||
return FolderIsMovable.HAS_LIVE_ITEMS;
|
||||
}
|
||||
|
||||
if (usedAssetsInFolder(movingFolder)) {
|
||||
return FolderIsMovable.HAS_IN_USE_ASSETS;
|
||||
}
|
||||
|
||||
return FolderIsMovable.YES;
|
||||
}
|
||||
|
||||
|
|
@ -434,6 +445,22 @@ public class FolderManager {
|
|||
return liveItemsInFolder || liveItemsInSubFolders;
|
||||
}
|
||||
|
||||
private boolean usedAssetsInFolder(final Folder folder) {
|
||||
|
||||
final boolean usedAssetsInFolder = folder.getObjects()
|
||||
.stream()
|
||||
.map(categorization -> categorization.getCategorizedObject())
|
||||
.filter(object -> object instanceof Asset)
|
||||
.map(asset -> (Asset) asset)
|
||||
.anyMatch(asset -> assetManager.isAssetInUse(asset));
|
||||
|
||||
final boolean usedAssetsInSubFolders = folder.getSubFolders()
|
||||
.stream()
|
||||
.anyMatch(subFolder -> usedAssetsInFolder(folder));
|
||||
|
||||
return usedAssetsInFolder || usedAssetsInSubFolders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path of folder.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue