CCM NG/ccm-cms: Next part of AssetPane
git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4652 8810af33-2d31-482b-a856-94f89814c4df
Former-commit-id: a78ab32db6
pull/2/head
parent
6f041f332e
commit
1af16deed7
|
|
@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class AssetFolderBrowser extends Table {
|
||||
|
||||
protected static final String SORT_ACTION_UP = "sortActionUp";
|
||||
protected static final String SORT_ACTION_DOWN = "sortActionDown";
|
||||
protected final static String SORT_KEY_NAME = "name";
|
||||
protected final static String SORT_KEY_TITLE = "title";
|
||||
protected final static String SORT_KEY_TYPE = "type";
|
||||
protected final static String SORT_KEY_LAST_MODIFIED_DATE = "lastModified";
|
||||
protected final static String SORT_KEY_CREATION_DATE = "creationDate";
|
||||
|
||||
private final 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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@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<AssetFolderBrowserTableRow> getAssetRows(final Folder folder,
|
||||
final String orderBy,
|
||||
final String orderDirection,
|
||||
final int firstResult,
|
||||
final int maxResults) {
|
||||
final List<Folder> subFolders = findSubFolders(folder,
|
||||
orderBy,
|
||||
orderDirection,
|
||||
firstResult,
|
||||
maxResults);
|
||||
final List<AssetFolderBrowserTableRow> subFolderRows = subFolders
|
||||
.stream()
|
||||
.map(subFolder -> buildRow(subFolder))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (subFolders.size() > maxResults) {
|
||||
return subFolderRows;
|
||||
} else {
|
||||
final int maxAssets = maxResults - subFolders.size();
|
||||
final int firstItem = firstResult - subFolders.size();
|
||||
|
||||
final List<Asset> assets = findAssetsInFolder(folder,
|
||||
orderBy,
|
||||
orderDirection,
|
||||
firstResult,
|
||||
maxResults);
|
||||
final List<AssetFolderBrowserTableRow> assetRows = assets
|
||||
.stream()
|
||||
.map(asset -> buildRow(asset))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
final List<AssetFolderBrowserTableRow> rows = new ArrayList<>();
|
||||
rows.addAll(subFolderRows);
|
||||
rows.addAll(assetRows);
|
||||
|
||||
return rows;
|
||||
}
|
||||
}
|
||||
|
||||
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<Folder> findSubFolders(final Folder folder,
|
||||
final String orderBy,
|
||||
final String orderDirection,
|
||||
final int firstResult,
|
||||
final int maxResults) {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
|
||||
final CriteriaQuery<Folder> criteria = builder
|
||||
.createQuery(Folder.class);
|
||||
final Root<Folder> from = criteria.from(Folder.class);
|
||||
|
||||
final Order order;
|
||||
if (AssetFolderBrowser.SORT_KEY_NAME.equals(orderBy)
|
||||
&& AssetFolderBrowser.SORT_ACTION_DOWN.equals(orderDirection)) {
|
||||
order = builder.desc(from.get("name"));
|
||||
} else {
|
||||
order = builder.asc(from.get("name"));
|
||||
}
|
||||
|
||||
final TypedQuery<Folder> query = entityManager
|
||||
.createQuery(
|
||||
criteria.where(
|
||||
builder.equal(from.get("parentCategory"), folder)
|
||||
)
|
||||
.orderBy(order)
|
||||
);
|
||||
|
||||
if (firstResult >= 0) {
|
||||
query.setFirstResult(firstResult);
|
||||
}
|
||||
|
||||
if (maxResults >= 0) {
|
||||
query.setMaxResults(maxResults);
|
||||
}
|
||||
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
private List<Asset> findAssetsInFolder(final Folder folder,
|
||||
final String orderBy,
|
||||
final String orderDirection,
|
||||
final int firstResult,
|
||||
final int maxResults) {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
|
||||
final CriteriaQuery<Asset> criteria = builder.createQuery(Asset.class);
|
||||
final Root<Asset> fromAsset = criteria.from(Asset.class);
|
||||
final Join<Asset, Category> join = fromAsset.join("categories");
|
||||
|
||||
final Path<?> orderPath;
|
||||
switch (orderBy) {
|
||||
case AssetFolderBrowser.SORT_KEY_NAME:
|
||||
orderPath = fromAsset.get("displayName");
|
||||
break;
|
||||
case AssetFolderBrowser.SORT_KEY_CREATION_DATE:
|
||||
orderPath = fromAsset.get("creationDate");
|
||||
break;
|
||||
case AssetFolderBrowser.SORT_KEY_LAST_MODIFIED_DATE:
|
||||
orderPath = fromAsset.get("lastModifed");
|
||||
break;
|
||||
default:
|
||||
orderPath = fromAsset.get("displayName");
|
||||
break;
|
||||
}
|
||||
|
||||
final Order order;
|
||||
if (AssetFolderBrowser.SORT_ACTION_DOWN.equals(orderDirection)) {
|
||||
order = builder.desc(orderPath);
|
||||
} else {
|
||||
order = builder.asc(orderPath);
|
||||
}
|
||||
|
||||
final TypedQuery<Asset> query = entityManager
|
||||
.createQuery(
|
||||
criteria.select(fromAsset)
|
||||
.where(
|
||||
builder.and(
|
||||
builder.equal(join.get("category"), folder),
|
||||
builder.equal(join.get("type"),
|
||||
CmsConstants.CATEGORIZATION_TYPE_FOLDER)
|
||||
)
|
||||
)
|
||||
.orderBy(order)
|
||||
);
|
||||
|
||||
if (firstResult >= 0) {
|
||||
query.setFirstResult(firstResult);
|
||||
}
|
||||
|
||||
if (maxResults >= 0) {
|
||||
query.setMaxResults(maxResults);
|
||||
}
|
||||
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
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<AssetFolderBrowserTableRow> iterator;
|
||||
private AssetFolderBrowserTableRow currentRow;
|
||||
|
||||
public AssetFolderBrowserTableModel(
|
||||
final List<AssetFolderBrowserTableRow> rows) {
|
||||
|
||||
iterator = rows.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return 6;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nextRow() {
|
||||
if (iterator.hasNext()) {
|
||||
currentRow = iterator.next();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getElementAt(final int columnIndex) {
|
||||
switch(columnIndex) {
|
||||
case COL_NAME:
|
||||
return currentRow.getName();
|
||||
case COL_TITLE:
|
||||
return currentRow.getTitle();
|
||||
case COL_TYPE:
|
||||
final String typeLabelBundle = currentRow.getTypeLabelBundle();
|
||||
final String typeLabelKey = currentRow.getTypeLabelKey();
|
||||
if (typeLabelKey == null) {
|
||||
return new GlobalizedMessage("empty_text",
|
||||
CmsConstants.CMS_BUNDLE);
|
||||
} else {
|
||||
return new GlobalizedMessage(typeLabelKey, typeLabelBundle);
|
||||
}
|
||||
case COL_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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class AssetFolderBrowserTableModelBuilder
|
||||
extends LockableImpl
|
||||
implements TableModelBuilder {
|
||||
|
||||
private static final Logger LOGGER = LogManager
|
||||
.getLogger(AssetFolderBrowserTableModelBuilder.class);
|
||||
|
||||
@Override
|
||||
public TableModel makeModel(final Table table,
|
||||
final PageState state) {
|
||||
|
||||
if (!(table instanceof AssetFolderBrowser)) {
|
||||
throw new IllegalArgumentException("The "
|
||||
+ "AssetFolderBrowserTableModelBuilder can only be used for the "
|
||||
+ "AssetFolderBrowser.");
|
||||
}
|
||||
|
||||
final AssetFolderBrowser assetFolderBrowser = (AssetFolderBrowser) table;
|
||||
final FolderSelectionModel folderSelectionModel = assetFolderBrowser
|
||||
.getFolderSelectionModel();
|
||||
final Folder folder = folderSelectionModel.getSelectedObject(state);
|
||||
if (folder == null) {
|
||||
return Table.EMPTY_MODEL;
|
||||
} else {
|
||||
assetFolderBrowser.getRowSelectionModel().clearSelection(state);
|
||||
final Paginator paginator = assetFolderBrowser.getPaginator();
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final AssetFolderBrowserController controller = cdiUtil
|
||||
.findBean(AssetFolderBrowserController.class);
|
||||
final String orderBy;
|
||||
if (assetFolderBrowser.getSortType(state) == null) {
|
||||
orderBy = AssetFolderBrowser.SORT_KEY_NAME;
|
||||
} else {
|
||||
orderBy = assetFolderBrowser.getSortType(state);
|
||||
}
|
||||
final String orderDirection;
|
||||
if (assetFolderBrowser.getSortDirection(state) == null) {
|
||||
orderDirection = AssetFolderBrowser.SORT_ACTION_UP;
|
||||
} else {
|
||||
orderDirection = assetFolderBrowser.getSortDirection(state);
|
||||
}
|
||||
final int first = paginator.getFirst(state);
|
||||
final int pageSize = paginator.getPageSize(state);
|
||||
|
||||
final long start = System.nanoTime();
|
||||
LOGGER.debug("Retrieving table rows...");
|
||||
final List<AssetFolderBrowserTableRow> rows = controller
|
||||
.getAssetRows(folder,
|
||||
orderBy,
|
||||
orderDirection,
|
||||
first - 1,
|
||||
pageSize);
|
||||
|
||||
LOGGER.debug("Retrieve table rows in {} ms.",
|
||||
(System.nanoTime() - start) / 1000);
|
||||
return new AssetFolderBrowserTableModel(rows);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class AssetFolderBrowserTableRow {
|
||||
|
||||
private long objectId;
|
||||
private String objectUuid;
|
||||
private String name;
|
||||
private String title;
|
||||
private String 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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<FolderBrowserTableRow> 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<FolderBrowserTableRow> 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<FolderBrowserTableRow> 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<FolderBrowserTableRow> getObjectRows(final Folder folder,
|
||||
|
|
@ -298,9 +300,10 @@ public class FolderBrowserController {
|
|||
orderDirection,
|
||||
firstResult,
|
||||
maxResults);
|
||||
final List<FolderBrowserTableRow> subFolderRows = subFolders.stream()
|
||||
.map(subFolder -> buildRow(subFolder))
|
||||
.collect(Collectors.toList());
|
||||
final List<FolderBrowserTableRow> 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<FolderBrowserTableRow> itemRows = items.stream()
|
||||
.map(item -> buildRow(item))
|
||||
.collect(Collectors.toList());
|
||||
.map(item -> buildRow(item))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
final ArrayList<FolderBrowserTableRow> rows = new ArrayList<>();
|
||||
final List<FolderBrowserTableRow> 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<Locale> 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<Folder> 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<Folder> criteria = builder.createQuery(
|
||||
Folder.class);
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
|
||||
final CriteriaQuery<Folder> criteria = builder
|
||||
.createQuery(Folder.class);
|
||||
final Root<Folder> from = criteria.from(Folder.class);
|
||||
|
||||
final Order order;
|
||||
if (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<Folder> query = entityManager.createQuery(
|
||||
criteria.where(builder.and(
|
||||
final TypedQuery<Folder> query = entityManager
|
||||
.createQuery(
|
||||
criteria.where(
|
||||
builder.and(
|
||||
builder.equal(from.get("parentCategory"), folder),
|
||||
builder
|
||||
.like(builder.lower(from.get("name")),
|
||||
filterTerm)))
|
||||
.orderBy(order));
|
||||
.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<ContentItem> 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<ContentItem> criteria = builder.createQuery(
|
||||
ContentItem.class);
|
||||
final CriteriaQuery<ContentItem> criteria = builder
|
||||
.createQuery(ContentItem.class);
|
||||
final Root<ContentItem> fromItem = criteria.from(ContentItem.class);
|
||||
final Join<ContentItem, Categorization> join = fromItem.join(
|
||||
"categories");
|
||||
final Join<ContentItem, Categorization> 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<ContentItem> 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<ContentItem> 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<String> 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<String> 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<List<String>> subFolderIds = sourceFolderIds
|
||||
.stream()
|
||||
.map(sourceFolderId -> findSubFolderIds(sourceFolderId))
|
||||
.collect(Collectors.toList());
|
||||
.stream()
|
||||
.map(sourceFolderId -> findSubFolderIds(sourceFolderId))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
final List<String> 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<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()));
|
||||
"%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<Folder> 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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ class FolderBrowserTableModel implements TableModel {
|
|||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return 6;
|
||||
return 7;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
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) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue