diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowser.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowser.java
new file mode 100644
index 000000000..4290562f8
--- /dev/null
+++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowser.java
@@ -0,0 +1,111 @@
+/*
+ * 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.event.TableActionListener;
+import com.arsdigita.bebop.parameters.StringParameter;
+import com.arsdigita.bebop.table.DefaultTableColumnModel;
+import com.arsdigita.bebop.table.TableColumn;
+import com.arsdigita.cms.ui.folder.FolderSelectionModel;
+import com.arsdigita.globalization.GlobalizedMessage;
+
+import javafx.scene.control.Pagination;
+import org.librecms.CmsConstants;
+
+/**
+ * Browse folder and assets.
+ *
+ * @author Jens Pelzetter
+ */
+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 FolderSelectionModel folderSelectionModel;
+ private TableActionListener folderChanger;
+ private TableActionListener tableDeleter;
+ 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 FolderSelectionModel folderSelectionModel) {
+ super();
+ sortTypeParameter.setDefaultValue(SORT_KEY_NAME);
+ sortDirectionParameter.setDefaultValue(SORT_ACTION_UP);
+
+ this.folderSelectionModel = folderSelectionModel;
+
+ initComponents();
+ }
+
+ protected FolderSelectionModel getFolderSelectionModel() {
+ return folderSelectionModel;
+ }
+
+ protected Paginator getPaginator() {
+ return paginator;
+ }
+
+ protected String getSortType(final PageState state) {
+ return (String) state.getValue(sortTypeParameter);
+ }
+
+ protected String getSortDirection(final PageState state) {
+ return (String) state.getValue(sortDirectionParameter);
+ }
+
+ private void initComponents() {
+ setModelBuilder(new AssetFolderBrowserTableModelBuilder());
+
+ final GlobalizedMessage[] headers = {
+ globalize("cms.ui.folder.name"),
+ globalize("cms.ui.folder.languages"),
+ globalize("cms.ui.folder.title"),
+ globalize("cms.ui.folder.type"),
+ globalize("cms.ui.folder.creation_date"),
+ globalize("cms.ui.folder.last_modified"),
+ globalize("cms.ui.folder.action")};
+ }
+
+ /**
+ * Getting the GlobalizedMessage using a CMS Class targetBundle.
+ *
+ * @param key The resource key
+ */
+ private GlobalizedMessage globalize(final String key) {
+ return new GlobalizedMessage(key, CmsConstants.CMS_FOLDER_BUNDLE);
+
+ }
+
+}
diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowserController.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowserController.java
new file mode 100644
index 000000000..bcf61dcf8
--- /dev/null
+++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowserController.java
@@ -0,0 +1,276 @@
+/*
+ * 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.ui.folder.FolderBrowser;
+import com.arsdigita.kernel.KernelConfig;
+
+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.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.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;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@RequestScoped
+public class AssetFolderBrowserController {
+
+ @Inject
+ private EntityManager entityManager;
+
+ @Inject
+ private ConfigurationManager confManager;
+
+ @Inject
+ private CategoryManager categoryManager;
+
+ @Inject
+ private AssetTypesManager typesManager;
+
+ @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 getAssetRows(final Folder folder,
+ final String orderBy,
+ final String orderDirection,
+ final int firstResult,
+ final int maxResults) {
+ final List subFolders = findSubFolders(folder,
+ orderBy,
+ orderDirection,
+ firstResult,
+ maxResults);
+ final List 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 firstItem = firstResult - subFolders.size();
+
+ final List assets = findAssetsInFolder(folder,
+ orderBy,
+ orderDirection,
+ firstResult,
+ maxResults);
+ final List assetRows = assets
+ .stream()
+ .map(asset -> buildRow(asset))
+ .collect(Collectors.toList());
+
+ final List rows = new ArrayList<>();
+ rows.addAll(subFolderRows);
+ rows.addAll(assetRows);
+
+ return rows;
+ }
+ }
+
+ 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));
+ }
+ final AssetTypeInfo typeInfo = typesManager
+ .getAssetTypeInfo(asset.getClass());
+ row.setTypeLabelBundle(typeInfo.getLabelBundle());
+ row.setTypeLabelKey(typeInfo.getLabelKey());
+
+ row.setFolder(false);
+
+ return row;
+ }
+
+ private List findSubFolders(final Folder folder,
+ final String orderBy,
+ final String orderDirection,
+ final int firstResult,
+ final int maxResults) {
+
+ final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
+
+ final CriteriaQuery criteria = builder
+ .createQuery(Folder.class);
+ final Root 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 query = entityManager
+ .createQuery(
+ criteria.where(
+ builder.equal(from.get("parentCategory"), folder)
+ )
+ .orderBy(order)
+ );
+
+ if (firstResult >= 0) {
+ query.setFirstResult(firstResult);
+ }
+
+ if (maxResults >= 0) {
+ query.setMaxResults(maxResults);
+ }
+
+ return query.getResultList();
+ }
+
+ private List findAssetsInFolder(final Folder folder,
+ final String orderBy,
+ final String orderDirection,
+ final int firstResult,
+ final int maxResults) {
+
+ final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
+
+ final CriteriaQuery criteria = builder.createQuery(Asset.class);
+ final Root fromAsset = criteria.from(Asset.class);
+ final Join 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);
+ }
+
+ final TypedQuery query = entityManager
+ .createQuery(
+ criteria.select(fromAsset)
+ .where(
+ builder.and(
+ builder.equal(join.get("category"), folder),
+ builder.equal(join.get("type"),
+ CmsConstants.CATEGORIZATION_TYPE_FOLDER)
+ )
+ )
+ .orderBy(order)
+ );
+
+ if (firstResult >= 0) {
+ query.setFirstResult(firstResult);
+ }
+
+ if (maxResults >= 0) {
+ query.setMaxResults(maxResults);
+ }
+
+ return query.getResultList();
+ }
+
+}
diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowserTableModel.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowserTableModel.java
new file mode 100644
index 000000000..9108a0f4b
--- /dev/null
+++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowserTableModel.java
@@ -0,0 +1,110 @@
+/*
+ * 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 Jens Pelzetter
+ */
+public class AssetFolderBrowserTableModel implements TableModel {
+
+ private static final int COL_NAME = 0;
+ private static final int COL_TITLE = 1;
+ private static final int COL_TYPE = 2;
+ private static final int COL_CREATION_DATE = 3;
+ private static final int COL_LAST_MODIFIED = 4;
+ private static final int COL_DELETEABLE = 5;
+
+ private final Iterator iterator;
+ private AssetFolderBrowserTableRow currentRow;
+
+ public AssetFolderBrowserTableModel(
+ final List 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_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("item-%d", currentRow.getObjectId());
+ }
+
+
+// return currentRow.getObjectId();
+ }
+
+ public boolean isFolder() {
+ return currentRow.isFolder();
+ }
+
+}
diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowserTableModelBuilder.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowserTableModelBuilder.java
new file mode 100644
index 000000000..c747c7a5f
--- /dev/null
+++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowserTableModelBuilder.java
@@ -0,0 +1,101 @@
+/*
+ * 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 Jens Pelzetter
+ */
+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 rows = controller
+ .getAssetRows(folder,
+ orderBy,
+ orderDirection,
+ first - 1,
+ pageSize);
+
+ LOGGER.debug("Retrieve table rows in {} ms.",
+ (System.nanoTime() - start) / 1000);
+ return new AssetFolderBrowserTableModel(rows);
+
+ }
+ }
+
+}
diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowserTableRow.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowserTableRow.java
new file mode 100644
index 000000000..5e3cefaf1
--- /dev/null
+++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowserTableRow.java
@@ -0,0 +1,139 @@
+/*
+ * 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 Jens Pelzetter
+ */
+class AssetFolderBrowserTableRow {
+
+ private long objectId;
+ private String objectUuid;
+ private String name;
+ private String title;
+ 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 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;
+ }
+
+
+
+
+}
diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetPane.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetPane.java
index 7856c6ab9..204edb332 100644
--- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetPane.java
+++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetPane.java
@@ -37,6 +37,7 @@ import com.arsdigita.bebop.event.PrintEvent;
import com.arsdigita.bebop.event.PrintListener;
import com.arsdigita.cms.CMS;
import com.arsdigita.cms.ui.BaseTree;
+import com.arsdigita.cms.ui.folder.FolderBrowser;
import com.arsdigita.cms.ui.folder.FolderCreateForm;
import com.arsdigita.cms.ui.folder.FolderEditorForm;
import com.arsdigita.cms.ui.folder.FolderRequestLocal;
@@ -142,6 +143,7 @@ public class AssetPane extends LayoutPanel implements Resettable {
browseSegment = panel.addSegment();
browseSegment.setIdAttr("folder-browse");
+
final ActionGroup actions = new ActionGroup();
browseSegment.add(actions);
diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/folder/FolderBrowser.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/folder/FolderBrowser.java
index f9b00dd22..abe4d03e4 100755
--- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/folder/FolderBrowser.java
+++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/folder/FolderBrowser.java
@@ -522,7 +522,7 @@ public class FolderBrowser extends Table {
/**
* Getting the GlobalizedMessage using a CMS Class targetBundle.
*
- * @param key The resource key @pre ( key != null )
+ * @param key The resource key
*/
private static GlobalizedMessage globalize(String key) {
return new GlobalizedMessage(key, CmsConstants.CMS_FOLDER_BUNDLE);
diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/folder/FolderBrowserController.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/folder/FolderBrowserController.java
index d22761ba6..09a6b8370 100644
--- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/folder/FolderBrowserController.java
+++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/folder/FolderBrowserController.java
@@ -125,7 +125,7 @@ public class FolderBrowserController {
@PostConstruct
private void init() {
final KernelConfig kernelConfig = confManager.findConfiguration(
- KernelConfig.class);
+ KernelConfig.class);
defaultLocale = kernelConfig.getDefaultLocale();
}
@@ -135,7 +135,7 @@ public class FolderBrowserController {
* @param folder The folder.
*
* @return The number of objects (subfolders and content items) in the
- * provided {@code folder}.
+ * provided {@code folder}.
*/
public long countObjects(final Folder folder) {
return countObjects(folder, "%");
@@ -145,11 +145,12 @@ public class FolderBrowserController {
* Count all objects (subfolders and content items) in the provided folder
* which match the provided filter term.
*
- * @param folder The folder.
+ * @param folder The folder.
* @param filterTerm The filter term.
*
* @return The number of objects (subfolders and content items) in the
- * provided {@code folder} which match the provided {@code filterTerm}.
+ * provided {@code folder} which match the provided
+ * {@code filterTerm}.
*/
public long countObjects(final Folder folder,
final String filterTerm) {
@@ -183,8 +184,8 @@ public class FolderBrowserController {
criteriaQuery = criteriaQuery.where(from.in(subFolders));
} else {
criteriaQuery = criteriaQuery.where(builder.or(
- from.in(subFolders),
- from.in(items)));
+ from.in(subFolders),
+ from.in(items)));
}
return entityManager.createQuery(criteriaQuery).getSingleResult();
@@ -194,13 +195,13 @@ public class FolderBrowserController {
* Create {@link FolderBrowserTableRow} objects for all objects in the
* provided folder.
*
- * @param folder The folder which contains the objects.
- * @param orderBy The field used to order the objects.
+ * @param folder The folder which contains the objects.
+ * @param orderBy The field used to order the objects.
* @param orderDirection The direction for ordering the objects.
*
* @return A list with {@link FolderBrowserTableRow} objects for each object
- * in the provided {@code folder} ordered by the provided field and in the
- * provided direction.
+ * in the provided {@code folder} ordered by the provided field and
+ * in the provided direction.
*/
@Transactional(Transactional.TxType.REQUIRED)
List getObjectRows(final Folder folder,
@@ -213,15 +214,15 @@ public class FolderBrowserController {
* Create {@link FolderBrowserTableRow} objects for all objects in the
* provided folder which match provided filter term.
*
- * @param folder The folder which contains the objects.
- * @param filterTerm The filter term.
- * @param orderBy The field used to order the objects.
+ * @param folder The folder which contains the objects.
+ * @param filterTerm The filter term.
+ * @param orderBy The field used to order the objects.
* @param orderDirection The direction for ordering the objects.
*
* @return A list with {@link FolderBrowserTableRow} objects for each object
- * in the provided {@code folder} which matches the provided
- * {@code filterTerm}, ordered by the provided field and in the provided
- * direction.
+ * in the provided {@code folder} which matches the provided
+ * {@code filterTerm}, ordered by the provided field and in the
+ * provided direction.
*/
@Transactional(Transactional.TxType.REQUIRED)
List getObjectRows(final Folder folder,
@@ -241,17 +242,17 @@ public class FolderBrowserController {
* provided folder which are in the range provided by {@code firstResult}
* and {@code maxResult}
*
- * @param folder The folder which contains the objects.
- * @param orderBy The field used to order the objects.
+ * @param folder The folder which contains the objects.
+ * @param orderBy The field used to order the objects.
* @param orderDirection The direction for ordering the objects.
- * @param firstResult The index of the first object to use.
- * @param maxResults The maximum number of objects to retrieve.
+ * @param firstResult The index of the first object to use.
+ * @param maxResults The maximum number of objects to retrieve.
*
* @return A list with {@link FolderBrowserTableRow} objects for each object
- * in the provided {@code folder} ordered by the provided field and in the
- * provided direction. The list will start with the object with index
- * provided as {@code firstResult} and contain at most {@code maxResults}
- * items.
+ * in the provided {@code folder} ordered by the provided field and
+ * in the provided direction. The list will start with the object
+ * with index provided as {@code firstResult} and contain at most
+ * {@code maxResults} items.
*/
@Transactional(Transactional.TxType.REQUIRED)
List getObjectRows(final Folder folder,
@@ -272,18 +273,19 @@ public class FolderBrowserController {
* provided folder which match the provided filter term and which are in the
* range provided by {@code firstResult} and {@code maxResult}
*
- * @param folder The folder which contains the objects.
- * @param filterTerm The filter term.
- * @param orderBy The field used to order the objects.
+ * @param folder The folder which contains the objects.
+ * @param filterTerm The filter term.
+ * @param orderBy The field used to order the objects.
* @param orderDirection The direction for ordering the objects.
- * @param firstResult The index of the first object to use.
- * @param maxResults The maximum number of objects to retrieve.
+ * @param firstResult The index of the first object to use.
+ * @param maxResults The maximum number of objects to retrieve.
*
* @return A list with {@link FolderBrowserTableRow} objects for each object
- * in the provided {@code folder} which matches the provided
- * {@code filterTerm}, ordered by the provided field and in the provided
- * direction. The list will start with the object with index provided as
- * {@code firstResult} and contain at most {@code maxResults} items.
+ * in the provided {@code folder} which matches the provided
+ * {@code filterTerm}, ordered by the provided field and in the
+ * provided direction. The list will start with the object with
+ * index provided as {@code firstResult} and contain at most
+ * {@code maxResults} items.
*/
@Transactional(Transactional.TxType.REQUIRED)
List getObjectRows(final Folder folder,
@@ -298,9 +300,10 @@ public class FolderBrowserController {
orderDirection,
firstResult,
maxResults);
- final List subFolderRows = subFolders.stream()
- .map(subFolder -> buildRow(subFolder))
- .collect(Collectors.toList());
+ final List subFolderRows = subFolders
+ .stream()
+ .map(subFolder -> buildRow(subFolder))
+ .collect(Collectors.toList());
if (subFolders.size() > maxResults) {
return subFolderRows;
@@ -315,10 +318,10 @@ public class FolderBrowserController {
firstItem,
maxItems);
final List itemRows = items.stream()
- .map(item -> buildRow(item))
- .collect(Collectors.toList());
+ .map(item -> buildRow(item))
+ .collect(Collectors.toList());
- final ArrayList rows = new ArrayList<>();
+ final List rows = new ArrayList<>();
rows.addAll(subFolderRows);
rows.addAll(itemRows);
@@ -331,10 +334,10 @@ public class FolderBrowserController {
* {@link Folder}.
*
* @param folder The {@link Folder} to use for building the
- * {@link FolderBrowserTableRow}.
+ * {@link FolderBrowserTableRow}.
*
* @return A {@link FolderBrowserTableRow} containing the data needed by the
- * {@link FolderBrowser} to display the provided {@code folder}.
+ * {@link FolderBrowser} to display the provided {@code folder}.
*/
private FolderBrowserTableRow buildRow(final Folder folder) {
@@ -345,15 +348,15 @@ public class FolderBrowserController {
row.setName(folder.getName());
row.setLanguages(Collections.emptyList());
if (folder.getTitle().hasValue(globalizationHelper
- .getNegotiatedLocale())) {
+ .getNegotiatedLocale())) {
row.setTitle(folder.getTitle().getValue(globalizationHelper
- .getNegotiatedLocale()));
+ .getNegotiatedLocale()));
} else {
row.setTitle(folder.getTitle().getValue(defaultLocale));
}
row.setFolder(true);
row.setDeletable(!categoryManager.hasSubCategories(folder)
- && !categoryManager.hasObjects(folder));
+ && !categoryManager.hasObjects(folder));
return row;
}
@@ -363,10 +366,10 @@ public class FolderBrowserController {
* {@link ContentItem}.
*
* @param item The {@link ContentItem} to use for building the
- * {@link FolderBrowserTableRow}.
+ * {@link FolderBrowserTableRow}.
*
* @return A {@link FolderBrowserTableRow} containing the data needed by the
- * {@link FolderBrowser} to display the provided {@code item}.
+ * {@link FolderBrowser} to display the provided {@code item}.
*/
private FolderBrowserTableRow buildRow(final ContentItem item) {
@@ -376,20 +379,20 @@ public class FolderBrowserController {
row.setObjectUuid(item.getItemUuid());
row.setName(item.getName().getValue(defaultLocale));
final List languages = new ArrayList<>(itemL10NManager
- .availableLanguages(item));
+ .availableLanguages(item));
languages.sort((lang1, lang2) -> lang1.toString().compareTo(
- lang2.toString()));
+ lang2.toString()));
row.setLanguages(languages);
if (item.getTitle().hasValue(globalizationHelper
- .getNegotiatedLocale())) {
+ .getNegotiatedLocale())) {
row.setTitle(item.getTitle().getValue(globalizationHelper
- .getNegotiatedLocale()));
+ .getNegotiatedLocale()));
} else {
row.setTitle(item.getTitle().getValue(defaultLocale));
}
final ContentType type = item.getContentType();
final ContentTypeInfo typeInfo = typesManager.getContentTypeInfo(
- type);
+ type);
row.setTypeLabelBundle(typeInfo.getLabelBundle());
row.setTypeLabelKey(typeInfo.getLabelKey());
@@ -415,21 +418,21 @@ public class FolderBrowserController {
if (objectId.startsWith("folder-")) {
final long folderId = Long.parseLong(
- objectId.substring("folder-".length()));
+ objectId.substring("folder-".length()));
folderRepo
- .findById(folderId)
- .ifPresent(folderRepo::delete);
+ .findById(folderId)
+ .ifPresent(folderRepo::delete);
} else if (objectId.startsWith("item-")) {
final long itemId = Long.parseLong(
- objectId.substring("item-".length()));
+ objectId.substring("item-".length()));
itemRepo
- .findById(itemId)
- .ifPresent(itemRepo::delete);
+ .findById(itemId)
+ .ifPresent(itemRepo::delete);
} else {
throw new IllegalArgumentException(
- "The objectId is expected to start with 'folder-' or 'item.'.");
+ "The objectId is expected to start with 'folder-' or 'item.'.");
}
}
@@ -445,20 +448,21 @@ public class FolderBrowserController {
* name in ascending and descending order depending on the value of
* {@code orderDirection}.
*
- * @param folder The folder which contains the subfolders.
- * @param filterTerm The filter term.
- * @param orderBy Field to use for ordering. If the value is negative the
- * parameter is ignored.
+ * @param folder The folder which contains the subfolders.
+ * @param filterTerm The filter term.
+ * @param orderBy Field to use for ordering. If the value is negative
+ * the parameter is ignored.
* @param orderDirection Direction for ordering. If the value is negative
- * the parameter is ignored.
- * @param firstResult Index of the first result to retrieve.
- * @param maxResults Maxium number of results to retrieve.
+ * the parameter is ignored.
+ * @param firstResult Index of the first result to retrieve.
+ * @param maxResults Maxium number of results to retrieve.
*
*
* @return A list of the subfolders of the provided {@code folder} which
- * match the provided {@code filterTerm}. The list is ordered as described
- * above. The list will contain at most {@code maxResults} starting with the
- * result with the index provided as {@code firstResult}.
+ * match the provided {@code filterTerm}. The list is ordered as
+ * described above. The list will contain at most {@code maxResults}
+ * starting with the result with the index provided as
+ * {@code firstResult}.
*/
private List findSubFolders(final Folder folder,
final String filterTerm,
@@ -466,28 +470,33 @@ public class FolderBrowserController {
final String orderDirection,
final int firstResult,
final int maxResults) {
- final CriteriaBuilder builder = entityManager
- .getCriteriaBuilder();
- final CriteriaQuery criteria = builder.createQuery(
- Folder.class);
+ final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
+
+ final CriteriaQuery criteria = builder
+ .createQuery(Folder.class);
final Root from = criteria.from(Folder.class);
final Order order;
if (FolderBrowser.SORT_KEY_NAME.equals(orderBy)
- && FolderBrowser.SORT_ACTION_DOWN.equals(orderDirection)) {
+ && FolderBrowser.SORT_ACTION_DOWN.equals(orderDirection)) {
order = builder.desc(from.get("name"));
} else {
order = builder.asc(from.get("name"));
}
- final TypedQuery query = entityManager.createQuery(
- criteria.where(builder.and(
+ final TypedQuery query = entityManager
+ .createQuery(
+ criteria.where(
+ builder.and(
builder.equal(from.get("parentCategory"), folder),
builder
- .like(builder.lower(from.get("name")),
- filterTerm)))
- .orderBy(order));
+ .like(builder.lower(from.get("name")),
+ filterTerm)
+ )
+ )
+ .orderBy(order)
+ );
if (firstResult >= 0) {
query.setFirstResult(firstResult);
@@ -502,21 +511,22 @@ public class FolderBrowserController {
/**
* Retrieves all items of a folder matching the provided filter term.
*
- * @param folder The folder which contains the subfolders.
- * @param filterTerm The filter term.
- * @param orderBy Field to use for ordering. If the value is negative the
- * parameter is ignored.
+ * @param folder The folder which contains the subfolders.
+ * @param filterTerm The filter term.
+ * @param orderBy Field to use for ordering. If the value is negative
+ * the parameter is ignored.
* @param orderDirection Direction for ordering. If the value is negative
- * the parameter is ignored.
- * @param firstResult Index of the first result to retrieve.
- * @param maxResults Maxium number of results to retrieve.
+ * the parameter is ignored.
+ * @param firstResult Index of the first result to retrieve.
+ * @param maxResults Maxium number of results to retrieve.
*
*
* @return A list of the subfolders of the provided {@code folder} which
- * match the provided {@code filterTerm}. The list is ordered the field
- * provided as {@code orderBy} in the direction provided by
- * {@code orderDirection}. The list will contain at most {@code maxResults}
- * starting with the result with the index provided as {@code firstResult}.
+ * match the provided {@code filterTerm}. The list is ordered the
+ * field provided as {@code orderBy} in the direction provided by
+ * {@code orderDirection}. The list will contain at most
+ * {@code maxResults} starting with the result with the index
+ * provided as {@code firstResult}.
*/
private List findItemsInFolder(final Folder folder,
final String filterTerm,
@@ -525,14 +535,13 @@ public class FolderBrowserController {
final int firstResult,
final int maxResults) {
- final CriteriaBuilder builder = entityManager
- .getCriteriaBuilder();
+ final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
- final CriteriaQuery criteria = builder.createQuery(
- ContentItem.class);
+ final CriteriaQuery criteria = builder
+ .createQuery(ContentItem.class);
final Root fromItem = criteria.from(ContentItem.class);
- final Join join = fromItem.join(
- "categories");
+ final Join join = fromItem
+ .join("categories");
final Path> orderPath;
switch (orderBy) {
@@ -543,7 +552,7 @@ public class FolderBrowserController {
orderPath = fromItem.get("creationDate");
break;
case FolderBrowser.SORT_KEY_LAST_MODIFIED_DATE:
- orderPath = fromItem.get("lastModified");
+ orderPath = fromItem.get("lastModifed");
break;
default:
orderPath = fromItem.get("displayName");
@@ -557,17 +566,22 @@ public class FolderBrowserController {
order = builder.asc(orderPath);
}
- final TypedQuery query = entityManager.createQuery(criteria
- .select(fromItem)
- .where(builder.and(
- builder.equal(join.get("category"), folder),
- builder.equal(join.get("type"),
- CmsConstants.CATEGORIZATION_TYPE_FOLDER),
- builder.equal(fromItem.get("version"),
- ContentItemVersion.DRAFT),
- builder.like(fromItem.get("displayName"),
- filterTerm)))
- .orderBy(order));
+ final TypedQuery query = entityManager
+ .createQuery(
+ criteria.select(fromItem)
+ .where(
+ builder.and(
+ builder.equal(join.get("category"), folder),
+ builder.equal(join.get("type"),
+ CmsConstants.CATEGORIZATION_TYPE_FOLDER),
+ builder.equal(fromItem.get("version"),
+ ContentItemVersion.DRAFT),
+ builder.like(fromItem.get("displayName"),
+ filterTerm)
+ )
+ )
+ .orderBy(order)
+ );
if (firstResult >= 0) {
query.setFirstResult(firstResult);
@@ -585,7 +599,7 @@ public class FolderBrowserController {
* @param folder The folder to check for live items.
*
* @return {@code true} if the {@code folder} or on of its subfolders
- * contains at least one live item, {@code false} otherwise.
+ * contains at least one live item, {@code false} otherwise.
*/
@Transactional(Transactional.TxType.REQUIRED)
public boolean hasLiveItems(final Folder folder) {
@@ -595,24 +609,24 @@ public class FolderBrowserController {
//Ensure that we use an non detached entity.
final Folder theFolder = folderRepo.findById(folder.getObjectId())
- .orElseThrow(() -> new IllegalArgumentException(String.format(
- "No folder with id %s in the database. Where did that ID come from?",
- folder.getObjectId())));
+ .orElseThrow(() -> new IllegalArgumentException(String.format(
+ "No folder with id %s in the database. Where did that ID come from?",
+ folder.getObjectId())));
final boolean hasLiveItem = theFolder.getObjects()
- .stream()
- .map(categorization -> categorization.getCategorizedObject())
- .filter(object -> object instanceof ContentItem)
- .map(object -> (ContentItem) object)
- .filter(item -> itemManager.isLive(item))
- .anyMatch(item -> itemManager.isLive(item));
+ .stream()
+ .map(categorization -> categorization.getCategorizedObject())
+ .filter(object -> object instanceof ContentItem)
+ .map(object -> (ContentItem) object)
+ .filter(item -> itemManager.isLive(item))
+ .anyMatch(item -> itemManager.isLive(item));
if (hasLiveItem) {
return true;
} else {
return theFolder.getSubFolders()
- .stream()
- .anyMatch(currentFolder -> hasLiveItems(currentFolder));
+ .stream()
+ .anyMatch(currentFolder -> hasLiveItems(currentFolder));
}
}
@@ -620,6 +634,7 @@ public class FolderBrowserController {
* Get the IDs of the folders invalid for copy/move actions.
*
* @param sources
+ *
* @return
*/
@Transactional(Transactional.TxType.REQUIRED)
@@ -628,20 +643,20 @@ public class FolderBrowserController {
Objects.requireNonNull(sources);
final List sourceFolderIds = sources
- .stream()
- .filter(source -> source.startsWith(
- FOLDER_BROWSER_KEY_PREFIX_FOLDER))
- .collect(Collectors.toList());
+ .stream()
+ .filter(source -> source.startsWith(
+ FOLDER_BROWSER_KEY_PREFIX_FOLDER))
+ .collect(Collectors.toList());
final List parentFolderIds = sourceFolderIds
- .stream()
- .map(sourceFolderId -> findParentFolderId(sourceFolderId))
- .filter(Optional::isPresent)
- .map(Optional::get)
- .collect(Collectors.toList());
+ .stream()
+ .map(sourceFolderId -> findParentFolderId(sourceFolderId))
+ .filter(Optional::isPresent)
+ .map(Optional::get)
+ .collect(Collectors.toList());
final List> subFolderIds = sourceFolderIds
- .stream()
- .map(sourceFolderId -> findSubFolderIds(sourceFolderId))
- .collect(Collectors.toList());
+ .stream()
+ .map(sourceFolderId -> findSubFolderIds(sourceFolderId))
+ .collect(Collectors.toList());
final List invalidTargetIds = new ArrayList<>();
invalidTargetIds.addAll(sourceFolderIds);
@@ -659,26 +674,26 @@ public class FolderBrowserController {
if (!folderId.startsWith(FOLDER_BROWSER_KEY_PREFIX_FOLDER)) {
throw new IllegalArgumentException(String.format(
- "Provided string '%s' is not an ID of a folder.",
- folderId));
+ "Provided string '%s' is not an ID of a folder.",
+ folderId));
}
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)
- .orElseThrow(() -> new IllegalArgumentException(String.format(
- "No folder with ID %d found in database. "
- + "Where did that ID come form?",
- objectId)));
+ .orElseThrow(() -> new IllegalArgumentException(String.format(
+ "No folder with ID %d found in database. "
+ + "Where did that ID come form?",
+ objectId)));
final Optional 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()));
+ "%s%d",
+ FOLDER_BROWSER_KEY_PREFIX_FOLDER,
+ parentFolder.get().getObjectId()));
}
}
@@ -688,23 +703,23 @@ public class FolderBrowserController {
if (!folderId.startsWith(FOLDER_BROWSER_KEY_PREFIX_FOLDER)) {
throw new IllegalArgumentException(String.format(
- "Provided string '%s' is not the ID of a folder.",
- folderId));
+ "Provided string '%s' is not the ID of a folder.",
+ folderId));
}
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)
- .orElseThrow(() -> new IllegalArgumentException(String.format(
- "No folder with ID %d found in database. "
- + "Where did that ID come form?",
- 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());
+ .stream()
+ .map(subFolder -> String.format("%s%d",
+ FOLDER_BROWSER_KEY_PREFIX_FOLDER,
+ subFolder.getObjectId()))
+ .collect(Collectors.toList());
}
private List findSubFolders(final Folder folder) {
@@ -712,7 +727,7 @@ public class FolderBrowserController {
Objects.requireNonNull(folder);
if (folder.getSubFolders() == null
- || folder.getSubFolders().isEmpty()) {
+ || folder.getSubFolders().isEmpty()) {
return Collections.emptyList();
}
@@ -736,17 +751,17 @@ public class FolderBrowserController {
if (objectId.startsWith(FOLDER_BROWSER_KEY_PREFIX_FOLDER)) {
moveFolder(targetFolder,
Long.parseLong(objectId.substring(
- FOLDER_BROWSER_KEY_PREFIX_FOLDER.length())));
+ 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())));
+ 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));
+ "ID '%s' does not start with '%s' or '%s'.",
+ objectId,
+ FOLDER_BROWSER_KEY_PREFIX_FOLDER,
+ FOLDER_BROWSER_KEY_PREFIX_ITEM));
}
}
}
@@ -756,11 +771,11 @@ public class FolderBrowserController {
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)));
-
+ .orElseThrow(() -> new IllegalArgumentException(String.format(
+ "No folder with ID %d in the database. "
+ + "Where did that ID come from?",
+ folderId)));
+
folderManager.moveFolder(folder, targetFolder);
}
@@ -769,10 +784,10 @@ public class FolderBrowserController {
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)));
+ .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);
}
@@ -788,46 +803,46 @@ public class FolderBrowserController {
if (objectId.startsWith(FOLDER_BROWSER_KEY_PREFIX_FOLDER)) {
copyFolder(targetFolder,
Long.parseLong(objectId.substring(
- FOLDER_BROWSER_KEY_PREFIX_FOLDER.length())));
+ 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())));
+ 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));
+ "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)));
-
+ .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)));
-
+ .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);
}
diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/folder/FolderBrowserTableModel.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/folder/FolderBrowserTableModel.java
index 7e00bdf62..a5a67f53b 100644
--- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/folder/FolderBrowserTableModel.java
+++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/folder/FolderBrowserTableModel.java
@@ -53,7 +53,7 @@ class FolderBrowserTableModel implements TableModel {
@Override
public int getColumnCount() {
- return 6;
+ return 7;
}
@Override
diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/folder/FolderBrowserTableModelBuilder.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/folder/FolderBrowserTableModelBuilder.java
index 742e3072f..9ac9fb939 100644
--- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/folder/FolderBrowserTableModelBuilder.java
+++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/folder/FolderBrowserTableModelBuilder.java
@@ -33,11 +33,12 @@ import org.librecms.contentsection.Folder;
import java.util.List;
/**
- * Creates the {@link TableModel} for the {@link FolderBrowser}.
- *
+ * Creates the {@link TableModel} for the {@link FolderBrowser}.
+ *
* @author Jens Pelzetter
*/
-class FolderBrowserTableModelBuilder extends LockableImpl
+class FolderBrowserTableModelBuilder
+ extends LockableImpl
implements TableModelBuilder {
private final static Logger LOGGER = LogManager.getLogger(
@@ -48,7 +49,8 @@ class FolderBrowserTableModelBuilder extends LockableImpl
final PageState state) {
if (!(table instanceof FolderBrowser)) {
throw new IllegalArgumentException(
- "The FolderBrowserTableModelBuilder can be used for the FolderBrowser.");
+ "The FolderBrowserTableModelBuilder can only be used for the "
+ + "FolderBrowser.");
}
final FolderBrowser folderBrowser = (FolderBrowser) table;
final FolderSelectionModel folderSelectionModel = folderBrowser
@@ -60,8 +62,8 @@ class FolderBrowserTableModelBuilder extends LockableImpl
folderBrowser.getRowSelectionModel().clearSelection(state);
final Paginator paginator = folderBrowser.getPaginator();
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
- final FolderBrowserController controller = cdiUtil.findBean(
- FolderBrowserController.class);
+ final FolderBrowserController controller = cdiUtil
+ .findBean(FolderBrowserController.class);
final String filter = folderBrowser.getFilter(state);
final String orderBy;
if (folderBrowser.getSortType(state) == null) {