CCM NG/ccm-cms: Still working on the FolderManipulator

git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4613 8810af33-2d31-482b-a856-94f89814c4df
jensp 2017-03-02 14:13:00 +00:00
parent be8df1b0e0
commit d23818c69c
7 changed files with 290 additions and 170 deletions

View File

@ -60,6 +60,10 @@ import javax.transaction.Transactional;
import javax.persistence.TypedQuery; import javax.persistence.TypedQuery;
import javax.persistence.criteria.Order; import javax.persistence.criteria.Order;
import javax.persistence.criteria.Path; import javax.persistence.criteria.Path;
import org.hibernate.tool.schema.internal.TargetFileImpl;
import org.libreccm.categorization.ObjectNotAssignedToCategoryException;
import org.libreccm.core.UnexpectedErrorException;
import org.librecms.contentsection.FolderManager;
import static org.librecms.CmsConstants.*; import static org.librecms.CmsConstants.*;
@ -77,6 +81,9 @@ public class FolderBrowserController {
@Inject @Inject
private EntityManager entityManager; private EntityManager entityManager;
@Inject
private CcmObjectRepository ccmObjectRepo;
@Inject @Inject
private CategoryManager categoryManager; private CategoryManager categoryManager;
@ -104,6 +111,9 @@ public class FolderBrowserController {
@Inject @Inject
private FolderRepository folderRepo; private FolderRepository folderRepo;
@Inject
private FolderManager folderManager;
private Locale defaultLocale; private Locale defaultLocale;
/** /**
@ -629,14 +639,14 @@ public class FolderBrowserController {
.map(Optional::get) .map(Optional::get)
.collect(Collectors.toList()); .collect(Collectors.toList());
final List<List<String>> subFolderIds = sourceFolderIds final List<List<String>> subFolderIds = sourceFolderIds
.stream() .stream()
.map(sourceFolderId -> findSubFolderIds(sourceFolderId)) .map(sourceFolderId -> findSubFolderIds(sourceFolderId))
.collect(Collectors.toList()); .collect(Collectors.toList());
final List<String> invalidTargetIds = new ArrayList<>(); final List<String> invalidTargetIds = new ArrayList<>();
invalidTargetIds.addAll(sourceFolderIds); invalidTargetIds.addAll(sourceFolderIds);
invalidTargetIds.addAll(parentFolderIds); invalidTargetIds.addAll(parentFolderIds);
for(final List<String> subFolderIdList : subFolderIds) { for (final List<String> subFolderIdList : subFolderIds) {
invalidTargetIds.addAll(subFolderIdList); invalidTargetIds.addAll(subFolderIdList);
} }
@ -679,7 +689,7 @@ public class FolderBrowserController {
"Provided string '%s' is not the ID of a folder.", "Provided string '%s' is not the ID of a folder.",
folderId)); folderId));
} }
final long objectId = Long.parseLong(folderId.substring( final long objectId = Long.parseLong(folderId.substring(
FOLDER_BROWSER_KEY_PREFIX_FOLDER.length())); FOLDER_BROWSER_KEY_PREFIX_FOLDER.length()));
final Folder folder = folderRepo.findById(objectId) final Folder folder = folderRepo.findById(objectId)
@ -689,28 +699,134 @@ public class FolderBrowserController {
objectId))); objectId)));
return findSubFolders(folder) return findSubFolders(folder)
.stream() .stream()
.map(subFolder -> String.format("%s%d", .map(subFolder -> String.format("%s%d",
FOLDER_BROWSER_KEY_PREFIX_FOLDER, FOLDER_BROWSER_KEY_PREFIX_FOLDER,
subFolder.getObjectId())) subFolder.getObjectId()))
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
private List<Folder> findSubFolders(final Folder folder) { private List<Folder> findSubFolders(final Folder folder) {
Objects.requireNonNull(folder); Objects.requireNonNull(folder);
if (folder.getSubFolders() == null if (folder.getSubFolders() == null
|| folder.getSubFolders().isEmpty()) { || folder.getSubFolders().isEmpty()) {
return Collections.emptyList(); return Collections.emptyList();
} }
final List<Folder> subFolders = new ArrayList<>(); final List<Folder> subFolders = new ArrayList<>();
for(final Folder subFolder : folder.getSubFolders()) { for (final Folder subFolder : folder.getSubFolders()) {
subFolders.add(subFolder); subFolders.add(subFolder);
subFolders.addAll(findSubFolders(subFolder)); subFolders.addAll(findSubFolders(subFolder));
} }
return subFolders; return subFolders;
} }
@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_ITEM)) {
moveItem(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_ITEM));
}
}
}
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 moveItem(final Folder targetFolder, final long itemId) {
Objects.requireNonNull(targetFolder);
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?",
itemId)));
itemManager.move(item, targetFolder);
}
@Transactional(Transactional.TxType.REQUIRED)
public 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_ITEM)) {
copyItem(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_ITEM));
}
}
}
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 copyItem(final Folder targetFolder,
final long itemId) {
Objects.requireNonNull(targetFolder);
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?",
itemId)));
itemManager.copy(item, targetFolder);
}
} }

View File

@ -203,55 +203,22 @@ public class FolderManipulator extends SimpleContainer implements
return (String) state.getValue(actionParam); return (String) state.getValue(actionParam);
} }
protected void moveItems(final Category target, protected void moveObjects(final Folder target, final String[] objectIds) {
final String[] itemIds) {
for (String itemId : itemIds) { final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final FolderBrowserController controller = cdiUtil.findBean(
changeItemParent(itemId, target); FolderBrowserController.class);
}
controller.moveObjects(target, objectIds);
} }
private void changeItemParent(final String itemId, protected void copyObjects(final Folder target, final String[] objectIds) {
final Category newParent) {
//ToDo final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
throw new UnsupportedOperationException(); final FolderBrowserController controller = cdiUtil.findBean(
FolderBrowserController.class);
// final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); controller.copyObjects(target, objectIds);
// final ContentItemRepository itemRepo = cdiUtil.findBean(
// ContentItemRepository.class);
// final ContentItemManager itemManager = cdiUtil.findBean(
// ContentItemManager.class);
// final CategoryManager categoryManager = cdiUtil.findBean(
// CategoryManager.class);
// final ContentItem item = itemRepo.findById(itemId);
// final Category itemFolder = itemManager.getItemFolders(item).
// item.addCategory(newParent);
// item.setParent(newParent);
// item.save();
}
protected void copyItems(final Category target,
final String[] itemIds) {
//ToDo
throw new UnsupportedOperationException();
//
// if (LOGGER.isDebugEnabled()) {
// LOGGER.debug("Copying items " + Arrays.asList(itemIds) + " to "
// + target);
// }
// for (BigDecimal itemId : itemIds) {
//
// final ContentItem source = retrieveSourceItem(itemId);
//
// final ContentItem newItem = source.copy(target, true);
// Assert.isEqual(target, newItem.getParent());
//
// }
} }
// protected void publishItems(final BigDecimal[] itemIds) { // protected void publishItems(final BigDecimal[] itemIds) {
@ -450,13 +417,13 @@ public class FolderManipulator extends SimpleContainer implements
itemView.setVisible(state, true); itemView.setVisible(state, true);
targetSelector.setVisible(state, false); targetSelector.setVisible(state, false);
final Category folder = targetSelector.getTarget(state); final Folder folder = targetSelector.getTarget(state);
final String[] itemIds = getSources(state); final String[] itemIds = getSources(state);
if (isCopy(state)) { if (isCopy(state)) {
copyItems(folder, itemIds); copyObjects(folder, itemIds);
} else if (isMove(state)) { } else if (isMove(state)) {
moveItems(folder, itemIds); moveObjects(folder, itemIds);
} }
reset(state); reset(state);

View File

@ -25,10 +25,10 @@ import com.arsdigita.cms.CMS;
import com.arsdigita.ui.CcmObjectSelectionModel; import com.arsdigita.ui.CcmObjectSelectionModel;
import org.libreccm.categorization.Category; import org.libreccm.categorization.Category;
import org.librecms.CmsConstants;
import org.librecms.contentsection.ContentSection; import org.librecms.contentsection.ContentSection;
import org.librecms.contentsection.Folder; import org.librecms.contentsection.Folder;
/** /**
* Keeps track of the selection of an item in a folder. The objects that are * Keeps track of the selection of an item in a folder. The objects that are
* selected by this model are all subclasses of {@link * selected by this model are all subclasses of {@link
@ -50,7 +50,7 @@ public class FolderSelectionModel extends CcmObjectSelectionModel<Folder> {
@Override @Override
public Long getSelectedKey(final PageState state) { public Long getSelectedKey(final PageState state) {
// FIXME: this code will go away once parameter models support init listeners // FIXME: this code will go away once parameter models support init listeners
Long result = super.getSelectedKey(state); final Long result = super.getSelectedKey(state);
if (result == null) { if (result == null) {
result = getRootFolderID(state); result = getRootFolderID(state);
setSelectedKey(state, result); setSelectedKey(state, result);
@ -62,11 +62,25 @@ public class FolderSelectionModel extends CcmObjectSelectionModel<Folder> {
public void setSelectedKey(final PageState state, final Long key) { public void setSelectedKey(final PageState state, final Long key) {
super.setSelectedKey(state, key); super.setSelectedKey(state, key);
} }
public void setSelectedKey(final PageState state, final String key) {
if (!key.startsWith(CmsConstants.FOLDER_BROWSER_KEY_PREFIX_FOLDER)) {
throw new IllegalArgumentException(String.format(
"The string '%s' does not contain a folder id "
+ "(it does not start with '%s').",
key,
CmsConstants.FOLDER_BROWSER_KEY_PREFIX_FOLDER));
}
final long keyAsLong = Long.parseLong(key.substring(
CmsConstants.FOLDER_BROWSER_KEY_PREFIX_FOLDER.length()));
setSelectedKey(state, keyAsLong);
}
/** /**
* Clear the selection by resetting it to the root folder id. * Clear the selection by resetting it to the root folder id.
* *
* @param state represents the cuerent request. * @param state represents the current request.
*/ */
@Override @Override
public void clearSelection(final PageState state) { public void clearSelection(final PageState state) {
@ -93,8 +107,9 @@ public class FolderSelectionModel extends CcmObjectSelectionModel<Folder> {
/** /**
* Return true, since this selection model will always have a folder * Return true, since this selection model will always have a folder
* selected in it * selected in it
*
* @param state * @param state
* @return * @return
*/ */
@Override @Override
public boolean isSelected(final PageState state) { public boolean isSelected(final PageState state) {

View File

@ -30,6 +30,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors;
import javax.enterprise.context.RequestScoped; import javax.enterprise.context.RequestScoped;
import javax.inject.Inject; import javax.inject.Inject;
@ -42,16 +43,16 @@ import javax.transaction.Transactional;
*/ */
@RequestScoped @RequestScoped
public class FolderManager { public class FolderManager {
@Inject @Inject
private ConfigurationManager confManager; private ConfigurationManager confManager;
@Inject @Inject
private FolderRepository folderRepo; private FolderRepository folderRepo;
@Inject @Inject
private CategoryManager categoryManager; private CategoryManager categoryManager;
@Inject @Inject
private ContentItemManager itemManager; private ContentItemManager itemManager;
@ -109,15 +110,16 @@ public class FolderManager {
*/ */
HAS_LIVE_ITEMS HAS_LIVE_ITEMS
} }
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public Optional<Folder> getParentFolder(final Folder folder) { public Optional<Folder> getParentFolder(final Folder folder) {
Objects.requireNonNull(folder); Objects.requireNonNull(folder);
final Optional<Folder> theFolder = folderRepo.findById(folder.getObjectId()); final Optional<Folder> theFolder = folderRepo.findById(folder.
getObjectId());
if (!theFolder.isPresent()) { if (!theFolder.isPresent()) {
throw new UnexpectedErrorException(String.format( throw new UnexpectedErrorException(String.format(
"The folder %s should be in the database but is not.", "The folder %s should be in the database but is not.",
Objects.toString(folder))); Objects.toString(folder)));
} }
final Category parentCategory = theFolder.get().getParentCategory(); final Category parentCategory = theFolder.get().getParentCategory();
if (parentCategory == null) { if (parentCategory == null) {
@ -126,13 +128,13 @@ public class FolderManager {
return folderRepo.findById(parentCategory.getObjectId()); return folderRepo.findById(parentCategory.getObjectId());
} }
} }
/** /**
* Creates new folder as sub folder of the provided parent folder. The type * Creates new folder as sub folder of the provided parent folder. The type
* and the content section to which the folder belongs are the same as for * and the content section to which the folder belongs are the same as for
* the provided parent folder. * the provided parent folder.
* *
* @param name The name of the new folder. * @param name The name of the new folder.
* @param parent The folder in which the new folder is generated. * @param parent The folder in which the new folder is generated.
* *
* @return The new folder. * @return The new folder.
@ -141,17 +143,17 @@ public class FolderManager {
public Folder createFolder(final String name, final Folder parent) { public Folder createFolder(final String name, final Folder parent) {
if (parent == null) { if (parent == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Can't create a folder without a parent folder."); "Can't create a folder without a parent folder.");
} }
if (name == null || name.trim().isEmpty()) { if (name == null || name.trim().isEmpty()) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Can't create a folder with an empty name"); "Can't create a folder with an empty name");
} }
final KernelConfig kernelConfig = confManager.findConfiguration( final KernelConfig kernelConfig = confManager.findConfiguration(
KernelConfig.class); KernelConfig.class);
final Folder folder = new Folder(); final Folder folder = new Folder();
folder.setName(name); folder.setName(name);
folder.setDisplayName(name); folder.setDisplayName(name);
@ -159,30 +161,30 @@ public class FolderManager {
folder.setSection(parent.getSection()); folder.setSection(parent.getSection());
folder.setType(parent.getType()); folder.setType(parent.getType());
folderRepo.save(folder); folderRepo.save(folder);
categoryManager.addSubCategoryToCategory(folder, parent); categoryManager.addSubCategoryToCategory(folder, parent);
return folder; return folder;
} }
public FolderIsDeletable folderIsDeletable(final Folder folder) { public FolderIsDeletable folderIsDeletable(final Folder folder) {
if (folder == null) { if (folder == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Can't check if null is deletable."); "Can't check if null is deletable.");
} }
if (!folder.getSubCategories().isEmpty()) { if (!folder.getSubCategories().isEmpty()) {
return FolderIsDeletable.HAS_SUBCATEGORIES; return FolderIsDeletable.HAS_SUBCATEGORIES;
} }
if (!folder.getObjects().isEmpty()) { if (!folder.getObjects().isEmpty()) {
return FolderIsDeletable.IS_NOT_EMPTY; return FolderIsDeletable.IS_NOT_EMPTY;
} }
if (!getParentFolder(folder).isPresent()) { if (!getParentFolder(folder).isPresent()) {
return FolderIsDeletable.IS_ROOT_FOLDER; return FolderIsDeletable.IS_ROOT_FOLDER;
} }
return FolderIsDeletable.YES; return FolderIsDeletable.YES;
} }
@ -196,7 +198,7 @@ public class FolderManager {
if (folder == null) { if (folder == null) {
throw new IllegalArgumentException("Can't delete folder null"); throw new IllegalArgumentException("Can't delete folder null");
} }
final FolderIsDeletable status = folderIsDeletable(folder); final FolderIsDeletable status = folderIsDeletable(folder);
switch (status) { switch (status) {
case YES: case YES:
@ -204,20 +206,20 @@ public class FolderManager {
break; break;
case HAS_SUBCATEGORIES: case HAS_SUBCATEGORIES:
throw new IllegalArgumentException(String.format( throw new IllegalArgumentException(String.format(
"Can't delete folder \"%s\" because the folder is not empty", "Can't delete folder \"%s\" because the folder is not empty",
getFolderPath(folder, true))); getFolderPath(folder, true)));
case IS_NOT_EMPTY: case IS_NOT_EMPTY:
throw new IllegalArgumentException(String.format( throw new IllegalArgumentException(String.format(
"Can't delete folder \"%s\" because the folder is not empty.", "Can't delete folder \"%s\" because the folder is not empty.",
getFolderPath(folder))); getFolderPath(folder)));
case IS_ROOT_FOLDER: case IS_ROOT_FOLDER:
throw new IllegalArgumentException( throw new IllegalArgumentException(
"The folder to delete is a root folder can can't be deleted."); "The folder to delete is a root folder can can't be deleted.");
default: default:
throw new IllegalArgumentException(String.format( throw new IllegalArgumentException(String.format(
"Unexpected return value from #folderIsDeletable: " "Unexpected return value from #folderIsDeletable: "
+ "\"%s\".", + "\"%s\".",
status.toString())); status.toString()));
} }
} }
@ -232,35 +234,27 @@ public class FolderManager {
*/ */
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public void moveFolder(final Folder folder, final Folder target) { public void moveFolder(final Folder folder, final Folder target) {
if (folder Objects.requireNonNull(folder, "Can't move folder null");
== null) { Objects.requireNonNull(target, "Can't move a folder to folder null");
throw new IllegalArgumentException("Can't move folder null");
}
if (target == null) {
throw new IllegalArgumentException(
"Can't move a folder to folder null");
}
final FolderIsMovable status = folderIsMovable(folder, target); final FolderIsMovable status = folderIsMovable(folder, target);
switch (status) { switch (status) {
case YES: { case YES: {
final Folder source = getParentFolder(folder).get(); final Folder source = getParentFolder(folder).get();
categoryManager.removeSubCategoryFromCategory(folder, source); categoryManager.removeSubCategoryFromCategory(folder, source);
final boolean sameName = target.getSubCategories() final boolean sameName = target.getSubCategories()
.stream() .stream()
.anyMatch(subCategory -> folder.getName().equals( .anyMatch(subCategory -> folder.getName().equals(
subCategory subCategory.getName()));
.getName()));
if (sameName) { if (sameName) {
final String name = String.format("%s_1", folder.getName()); final String name = String.format("%s_1", folder.getName());
folder.setName(name); folder.setName(name);
folder.setDisplayName(name); folder.setDisplayName(name);
final KernelConfig kernelConfig = confManager. final KernelConfig kernelConfig = confManager.
findConfiguration( findConfiguration(
KernelConfig.class); KernelConfig.class);
folder.getTitle().addValue(kernelConfig.getDefaultLocale(), folder.getTitle().addValue(kernelConfig.getDefaultLocale(),
name); name);
} }
@ -269,36 +263,36 @@ public class FolderManager {
} }
case IS_ROOT_FOLDER: case IS_ROOT_FOLDER:
throw new IllegalArgumentException(String.format( throw new IllegalArgumentException(String.format(
"The folder \"%s\" to move is a root folder can can't " "The folder \"%s\" to move is a root folder can can't "
+ "be moved.", + "be moved.",
getFolderPath(folder))); getFolderPath(folder)));
case SAME_FOLDER: case SAME_FOLDER:
throw new IllegalArgumentException( throw new IllegalArgumentException(
"The folder to move and the target folder are the same " "The folder to move and the target folder are the same "
+ "folder."); + "folder.");
case DIFFERENT_SECTIONS: case DIFFERENT_SECTIONS:
throw new IllegalArgumentException(String.format( throw new IllegalArgumentException(String.format(
"Folders can't be moved between content section. The " "Folders can't be moved between content section. The "
+ "folder \"%s\" to move belongs to section " + "folder \"%s\" to move belongs to section "
+ "\"%s\", the target folder \"%s\" belongs to " + "\"%s\", the target folder \"%s\" belongs to "
+ "section \"%s\".", + "section \"%s\".",
getFolderPath(folder), getFolderPath(folder),
folder.getSection().getDisplayName(), folder.getSection().getDisplayName(),
getFolderPath(target), getFolderPath(target),
target.getSection().getDisplayName())); target.getSection().getDisplayName()));
case DIFFERENT_TYPES: case DIFFERENT_TYPES:
throw new IllegalArgumentException( throw new IllegalArgumentException(
"The folder to move is a \"%s\"," "The folder to move is a \"%s\","
+ "but the target folder is a \"%s\" folder."); + "but the target folder is a \"%s\" folder.");
case HAS_LIVE_ITEMS: case HAS_LIVE_ITEMS:
throw new IllegalArgumentException(String.format( throw new IllegalArgumentException(String.format(
"Can't move folder \"%s\" because some items in the " "Can't move folder \"%s\" because some items in the "
+ "folder or its sub folder are live.", + "folder or its sub folder are live.",
getFolderPath(folder, true))); getFolderPath(folder, true)));
default: default:
throw new IllegalArgumentException(String.format( throw new IllegalArgumentException(String.format(
"Unexpected return value from #folderIsMovable: %s", "Unexpected return value from #folderIsMovable: %s",
status.toString())); status.toString()));
} }
// if (folder.getParentFolder() // if (folder.getParentFolder()
@ -357,40 +351,62 @@ public class FolderManager {
// //
// categoryManager.addSubCategoryToCategory(folder, target); // categoryManager.addSubCategoryToCategory(folder, target);
} }
public FolderIsMovable folderIsMovable(final Folder folder, public FolderIsMovable folderIsMovable(final Folder folder,
final Folder target) { final Folder target) {
if (folder == null) { if (folder == null) {
throw new IllegalArgumentException("Can't check if null is movable."); throw new IllegalArgumentException("Can't check if null is movable.");
} }
if (target == null) { if (target == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Can't check if a server can be moved to null."); "Can't check if a server can be moved to null.");
} }
if (!getParentFolder(folder).isPresent()) { if (!getParentFolder(folder).isPresent()) {
return FolderIsMovable.IS_ROOT_FOLDER; return FolderIsMovable.IS_ROOT_FOLDER;
} }
if (folder.equals(target)) { if (folder.equals(target)) {
return FolderIsMovable.SAME_FOLDER; return FolderIsMovable.SAME_FOLDER;
} }
if (!folder.getSection().equals(target.getSection())) { if (!folder.getSection().equals(target.getSection())) {
return FolderIsMovable.DIFFERENT_SECTIONS; return FolderIsMovable.DIFFERENT_SECTIONS;
} }
if (folder.getType() != target.getType()) { if (folder.getType() != target.getType()) {
return FolderIsMovable.DIFFERENT_TYPES; return FolderIsMovable.DIFFERENT_TYPES;
} }
if (liveItemsInFolder(folder)) { if (liveItemsInFolder(folder)) {
return FolderIsMovable.HAS_LIVE_ITEMS; return FolderIsMovable.HAS_LIVE_ITEMS;
} }
return FolderIsMovable.YES; return FolderIsMovable.YES;
} }
@Transactional(Transactional.TxType.REQUIRED)
public void copyFolder(final Folder folder, final Folder target) {
Objects.requireNonNull(folder, "Can't move null to a folder.");
Objects.requireNonNull(target, "Can't move a folder to null.");
final Folder copy = createFolder(folder.getName(), target);
final List<ContentItem> items = folder.getObjects()
.stream()
.map(categorization -> categorization.getCategorizedObject())
.filter(object -> object instanceof ContentItem)
.map(object -> (ContentItem) object)
.collect(Collectors.toList());
for (final ContentItem item : items) {
itemManager.copy(item, target);
}
for(final Folder subFolder : folder.getSubFolders()) {
copyFolder(subFolder, copy);
}
}
/** /**
* Internal helper method for checking if there any live items in a given * Internal helper method for checking if there any live items in a given
@ -399,20 +415,20 @@ public class FolderManager {
* @param folder The folder to check for live items. * @param folder The folder to check for live items.
* *
* @return {@code true} if there any live items in the folder or its sub * @return {@code true} if there any live items in the folder or its sub
* folders, {@code false} if not. * folders, {@code false} if not.
*/ */
private boolean liveItemsInFolder(final Folder folder) { private boolean liveItemsInFolder(final Folder folder) {
final boolean liveItemsInFolder = folder.getObjects() final boolean liveItemsInFolder = folder.getObjects()
.stream() .stream()
.map(categorization -> categorization.getCategorizedObject()) .map(categorization -> categorization.getCategorizedObject())
.filter(object -> object instanceof ContentItem) .filter(object -> object instanceof ContentItem)
.map(object -> (ContentItem) object) .map(object -> (ContentItem) object)
.anyMatch(item -> itemManager.isLive(item)); .anyMatch(item -> itemManager.isLive(item));
final boolean liveItemsInSubFolders = folder.getSubFolders() final boolean liveItemsInSubFolders = folder.getSubFolders()
.stream() .stream()
.anyMatch(subFolder -> liveItemsInFolder(subFolder)); .anyMatch(subFolder -> liveItemsInFolder(subFolder));
return liveItemsInFolder || liveItemsInSubFolders; return liveItemsInFolder || liveItemsInSubFolders;
} }
@ -422,7 +438,7 @@ public class FolderManager {
* @param folder The folder. * @param folder The folder.
* *
* @return The path of the folder as a UNIX-like path, but without the * @return The path of the folder as a UNIX-like path, but without the
* content section as prefix. * content section as prefix.
*/ */
public String getFolderPath(final Folder folder) { public String getFolderPath(final Folder folder) {
return getFolderPath(folder, false); return getFolderPath(folder, false);
@ -431,31 +447,31 @@ public class FolderManager {
/** /**
* Returns the path of folder. * Returns the path of folder.
* *
* @param folder The folder. * @param folder The folder.
* @param withContentSection Whether to include the content section in the * @param withContentSection Whether to include the content section in the
* path. * path.
* *
* @return The path of the folder as a UNIX-like path, optionally with the * @return The path of the folder as a UNIX-like path, optionally with the
* content section the folder belongs to as prefix.. * content section the folder belongs to as prefix..
*/ */
public String getFolderPath(final Folder folder, public String getFolderPath(final Folder folder,
final boolean withContentSection) { final boolean withContentSection) {
if (folder == null) { if (folder == null) {
throw new IllegalArgumentException("Can't generate a path for null."); throw new IllegalArgumentException("Can't generate a path for null.");
} }
final List<String> tokens = new ArrayList<>(); final List<String> tokens = new ArrayList<>();
tokens.add(folder.getName()); tokens.add(folder.getName());
Folder current = folder; Folder current = folder;
while (getParentFolder(current).isPresent()) { while (getParentFolder(current).isPresent()) {
current = getParentFolder(current).get(); current = getParentFolder(current).get();
tokens.add(current.getName()); tokens.add(current.getName());
} }
Collections.reverse(tokens); Collections.reverse(tokens);
final String path = String.join("/", tokens); final String path = String.join("/", tokens);
if (withContentSection) { if (withContentSection) {
final String sectionName = folder.getSection().getDisplayName(); final String sectionName = folder.getSection().getDisplayName();
return String.format("%s:/%s/", sectionName, path); return String.format("%s:/%s/", sectionName, path);
@ -473,16 +489,16 @@ public class FolderManager {
*/ */
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public List<Folder> getParentFolders(final Folder folder) { public List<Folder> getParentFolders(final Folder folder) {
if (folder == null) { if (folder == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Can't create a list of parent folder for folder null."); "Can't create a list of parent folder for folder null.");
} }
final List<Folder> folders = new ArrayList<>(); final List<Folder> folders = new ArrayList<>();
if (getParentFolder(folder).isPresent()) { if (getParentFolder(folder).isPresent()) {
Optional<Folder> currentFolder = getParentFolder(folder); Optional<Folder> currentFolder = getParentFolder(folder);
while(currentFolder.isPresent()) { while (currentFolder.isPresent()) {
folders.add(currentFolder.get()); folders.add(currentFolder.get());
currentFolder = getParentFolder(currentFolder.get()); currentFolder = getParentFolder(currentFolder.get());
} }
@ -491,5 +507,5 @@ public class FolderManager {
Collections.reverse(folders); Collections.reverse(folders);
return folders; return folders;
} }
} }

View File

@ -123,3 +123,5 @@ cms.contenttypes.ui.name=Name (URL fragment)
cms.ui.content_section=Content Section: cms.ui.content_section=Content Section:
cms.ui.folderform.error.child.name_not_unique=The current folder already contains a child with the name {0}. cms.ui.folderform.error.child.name_not_unique=The current folder already contains a child with the name {0}.
cms.ui.folderform.error.parent.name_not_unique=The parent folder of the selected folder already contains a child with the name {0}. cms.ui.folderform.error.parent.name_not_unique=The parent folder of the selected folder already contains a child with the name {0}.
cms.ui.choose_target_folder=Choose target folder
cms.ui.folder.copy=Copy {0} items from {1}

View File

@ -122,3 +122,5 @@ cms.contenttypes.ui.name=Name (URL-Fragment)
cms.ui.content_section=Content Section: cms.ui.content_section=Content Section:
cms.ui.folderform.error.child.name_not_unique=Der derzeit ausgew\u00e4hlte Ordner enth\u00e4lt bereits einen Ordner oder ein Dokument mit dem Namen {0}. cms.ui.folderform.error.child.name_not_unique=Der derzeit ausgew\u00e4hlte Ordner enth\u00e4lt bereits einen Ordner oder ein Dokument mit dem Namen {0}.
cms.ui.folderform.error.parent.name_not_unique=Der \u00fcbergeordnete Ordner enth\u00e4lt bereits einen ein Objekt mit dem Namen {0}. cms.ui.folderform.error.parent.name_not_unique=Der \u00fcbergeordnete Ordner enth\u00e4lt bereits einen ein Objekt mit dem Namen {0}.
cms.ui.choose_target_folder=Zielordner ausw\u00e4hlen
cms.ui.folder.copy=Kopiere {0} Dokumente von {1} nach

View File

@ -91,3 +91,5 @@ cms.contenttypes.ui.name=Name (URL fragment)
cms.ui.content_section=Content Section: cms.ui.content_section=Content Section:
cms.ui.folderform.error.child.name_not_unique=The current folder already contains a child with the name {0}. cms.ui.folderform.error.child.name_not_unique=The current folder already contains a child with the name {0}.
cms.ui.folderform.error.parent.name_not_unique=The parent folder of the selected folder already contains a child with the name {0}. cms.ui.folderform.error.parent.name_not_unique=The parent folder of the selected folder already contains a child with the name {0}.
cms.ui.choose_target_folder=Choose target folder
cms.ui.folder.copy=Copy {0} items from {1}