CCM NG/ccm-cms: Thumbnails for images in AssetBrowser
git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4888 8810af33-2d31-482b-a856-94f89814c4df
Former-commit-id: f7d7293868
pull/2/head
parent
01954befb0
commit
776e1719d3
|
|
@ -101,6 +101,8 @@ public class AssetFolderBrowser extends Table {
|
|||
CMS_FOLDER_BUNDLE),
|
||||
new GlobalizedMessage("cms.ui.folder.type",
|
||||
CMS_FOLDER_BUNDLE),
|
||||
new GlobalizedMessage("cms.ui.asset.thumbnail",
|
||||
CMS_BUNDLE),
|
||||
new GlobalizedMessage("cms.ui.folder.creation_date",
|
||||
CMS_FOLDER_BUNDLE),
|
||||
new GlobalizedMessage("cms.ui.folder.last_modified",
|
||||
|
|
@ -120,6 +122,9 @@ public class AssetFolderBrowser extends Table {
|
|||
nameColumn.setCellRenderer(new NameCellRenderer());
|
||||
nameColumn.setHeaderRenderer(new HeaderCellRenderer(SORT_KEY_NAME));
|
||||
|
||||
getColumn(AssetFolderBrowserTableModel.COL_THUMBNAIL)
|
||||
.setCellRenderer(new ThumbnailCellRenderer());
|
||||
|
||||
getColumn(AssetFolderBrowserTableModel.COL_CREATION_DATE)
|
||||
.setHeaderRenderer(
|
||||
new HeaderCellRenderer(SORT_KEY_CREATION_DATE));
|
||||
|
|
@ -305,6 +310,26 @@ public class AssetFolderBrowser extends Table {
|
|||
|
||||
}
|
||||
|
||||
private class ThumbnailCellRenderer implements TableCellRenderer {
|
||||
|
||||
@Override
|
||||
public Component getComponent(final Table table,
|
||||
final PageState state,
|
||||
final Object value,
|
||||
final boolean isSelected,
|
||||
final Object key,
|
||||
final int row,
|
||||
final int column) {
|
||||
if (value == null) {
|
||||
return new Text("");
|
||||
} else {
|
||||
final Image image = new Image((String) value, "");
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class DateCellRenderer implements TableCellRenderer {
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -18,7 +18,9 @@
|
|||
*/
|
||||
package com.arsdigita.cms.ui.assets;
|
||||
|
||||
import com.arsdigita.cms.CMS;
|
||||
import com.arsdigita.kernel.KernelConfig;
|
||||
import com.arsdigita.web.CCMDispatcherServlet;
|
||||
|
||||
import org.libreccm.categorization.Category;
|
||||
import org.libreccm.categorization.CategoryManager;
|
||||
|
|
@ -58,8 +60,10 @@ import org.librecms.contentsection.FolderRepository;
|
|||
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.librecms.assets.Image;
|
||||
|
||||
import static org.librecms.CmsConstants.*;
|
||||
|
||||
|
|
@ -71,7 +75,7 @@ import static org.librecms.CmsConstants.*;
|
|||
public class AssetFolderBrowserController {
|
||||
|
||||
private static final Logger LOGGER = LogManager
|
||||
.getLogger(AssetFolderBrowserController.class);
|
||||
.getLogger(AssetFolderBrowserController.class);
|
||||
|
||||
@Inject
|
||||
private EntityManager entityManager;
|
||||
|
|
@ -111,7 +115,7 @@ public class AssetFolderBrowserController {
|
|||
@PostConstruct
|
||||
private void init() {
|
||||
final KernelConfig kernelConfig = confManager.findConfiguration(
|
||||
KernelConfig.class);
|
||||
KernelConfig.class);
|
||||
defaultLocale = kernelConfig.getDefaultLocale();
|
||||
}
|
||||
|
||||
|
|
@ -128,9 +132,9 @@ public class AssetFolderBrowserController {
|
|||
firstResult,
|
||||
maxResults);
|
||||
final List<AssetFolderBrowserTableRow> subFolderRows = subFolders
|
||||
.stream()
|
||||
.map(subFolder -> buildRow(subFolder))
|
||||
.collect(Collectors.toList());
|
||||
.stream()
|
||||
.map(subFolder -> buildRow(subFolder))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (subFolders.size() > maxResults) {
|
||||
return subFolderRows;
|
||||
|
|
@ -145,9 +149,9 @@ public class AssetFolderBrowserController {
|
|||
firstAsset,
|
||||
maxAssets);
|
||||
final List<AssetFolderBrowserTableRow> assetRows = assets
|
||||
.stream()
|
||||
.map(asset -> buildRow(asset))
|
||||
.collect(Collectors.toList());
|
||||
.stream()
|
||||
.map(asset -> buildRow(asset))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
final List<AssetFolderBrowserTableRow> rows = new ArrayList<>();
|
||||
rows.addAll(subFolderRows);
|
||||
|
|
@ -177,19 +181,19 @@ public class AssetFolderBrowserController {
|
|||
criteriaQuery = criteriaQuery.select(builder.count(from));
|
||||
|
||||
final List<Folder> subFolders = findSubFolders(
|
||||
folder,
|
||||
filterTerm,
|
||||
AssetFolderBrowser.SORT_KEY_NAME,
|
||||
AssetFolderBrowser.SORT_ACTION_UP,
|
||||
-1,
|
||||
-1);
|
||||
folder,
|
||||
filterTerm,
|
||||
AssetFolderBrowser.SORT_KEY_NAME,
|
||||
AssetFolderBrowser.SORT_ACTION_UP,
|
||||
-1,
|
||||
-1);
|
||||
final List<Asset> assets = findAssetsInFolder(
|
||||
folder,
|
||||
filterTerm,
|
||||
AssetFolderBrowser.SORT_KEY_NAME,
|
||||
AssetFolderBrowser.SORT_ACTION_UP,
|
||||
-1,
|
||||
-1);
|
||||
folder,
|
||||
filterTerm,
|
||||
AssetFolderBrowser.SORT_KEY_NAME,
|
||||
AssetFolderBrowser.SORT_ACTION_UP,
|
||||
-1,
|
||||
-1);
|
||||
|
||||
if (subFolders.isEmpty() && assets.isEmpty()) {
|
||||
return 0;
|
||||
|
|
@ -199,8 +203,8 @@ public class AssetFolderBrowserController {
|
|||
criteriaQuery = criteriaQuery.where(from.in(subFolders));
|
||||
} else {
|
||||
criteriaQuery = criteriaQuery.where(builder.or(
|
||||
from.in(subFolders),
|
||||
from.in(assets)));
|
||||
from.in(subFolders),
|
||||
from.in(assets)));
|
||||
}
|
||||
|
||||
return entityManager.createQuery(criteriaQuery).getSingleResult();
|
||||
|
|
@ -218,17 +222,17 @@ public class AssetFolderBrowserController {
|
|||
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_ASSET)) {
|
||||
copyAsset(targetFolder,
|
||||
Long.parseLong(objectId.substring(
|
||||
FOLDER_BROWSER_KEY_PREFIX_ASSET.length())));
|
||||
FOLDER_BROWSER_KEY_PREFIX_ASSET.length())));
|
||||
} else {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"ID '%s' does not start with '%s' or '%s'.",
|
||||
objectId,
|
||||
FOLDER_BROWSER_KEY_PREFIX_FOLDER,
|
||||
FOLDER_BROWSER_KEY_PREFIX_ASSET));
|
||||
"ID '%s' does not start with '%s' or '%s'.",
|
||||
objectId,
|
||||
FOLDER_BROWSER_KEY_PREFIX_FOLDER,
|
||||
FOLDER_BROWSER_KEY_PREFIX_ASSET));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -240,10 +244,10 @@ public class AssetFolderBrowserController {
|
|||
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);
|
||||
|
||||
|
|
@ -255,10 +259,10 @@ public class AssetFolderBrowserController {
|
|||
Objects.requireNonNull(targetFolder);
|
||||
|
||||
final Asset asset = assetRepo
|
||||
.findById(assetId)
|
||||
.orElseThrow(() -> new IllegalArgumentException(String.format(
|
||||
"No asset ith ID %d in the database. Where did that ID come from?",
|
||||
assetId)));
|
||||
.findById(assetId)
|
||||
.orElseThrow(() -> new IllegalArgumentException(String.format(
|
||||
"No asset ith ID %d in the database. Where did that ID come from?",
|
||||
assetId)));
|
||||
|
||||
assetManager.copy(asset, targetFolder);
|
||||
}
|
||||
|
|
@ -274,17 +278,17 @@ public class AssetFolderBrowserController {
|
|||
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_ASSET)) {
|
||||
moveAsset(targetFolder,
|
||||
Long.parseLong(objectId.substring(
|
||||
FOLDER_BROWSER_KEY_PREFIX_ASSET.length())));
|
||||
FOLDER_BROWSER_KEY_PREFIX_ASSET.length())));
|
||||
} else {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"ID '%s' does not start with '%s' or '%s'.",
|
||||
objectId,
|
||||
FOLDER_BROWSER_KEY_PREFIX_FOLDER,
|
||||
FOLDER_BROWSER_KEY_PREFIX_ASSET));
|
||||
"ID '%s' does not start with '%s' or '%s'.",
|
||||
objectId,
|
||||
FOLDER_BROWSER_KEY_PREFIX_FOLDER,
|
||||
FOLDER_BROWSER_KEY_PREFIX_ASSET));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -294,10 +298,10 @@ public class AssetFolderBrowserController {
|
|||
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);
|
||||
}
|
||||
|
|
@ -307,10 +311,10 @@ public class AssetFolderBrowserController {
|
|||
Objects.requireNonNull(targetFolder);
|
||||
|
||||
final Asset asset = assetRepo
|
||||
.findById(assetId)
|
||||
.orElseThrow(() -> new IllegalArgumentException(String.format(
|
||||
"No asset with ID %d in the database. Where did that ID come from?",
|
||||
assetId)));
|
||||
.findById(assetId)
|
||||
.orElseThrow(() -> new IllegalArgumentException(String.format(
|
||||
"No asset with ID %d in the database. Where did that ID come from?",
|
||||
assetId)));
|
||||
|
||||
assetManager.move(asset, targetFolder);
|
||||
}
|
||||
|
|
@ -321,20 +325,20 @@ public class AssetFolderBrowserController {
|
|||
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);
|
||||
|
|
@ -353,26 +357,26 @@ public class AssetFolderBrowserController {
|
|||
|
||||
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);
|
||||
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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -382,23 +386,23 @@ public class AssetFolderBrowserController {
|
|||
|
||||
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) {
|
||||
|
|
@ -406,7 +410,7 @@ public class AssetFolderBrowserController {
|
|||
Objects.requireNonNull(folder);
|
||||
|
||||
if (folder.getSubFolders() == null
|
||||
|| folder.getSubFolders().isEmpty()) {
|
||||
|| folder.getSubFolders().isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
|
|
@ -431,21 +435,21 @@ public class AssetFolderBrowserController {
|
|||
|
||||
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("asset-")) {
|
||||
final long assetId = Long.parseLong(
|
||||
objectId.substring("asset-".length()));
|
||||
objectId.substring("asset-".length()));
|
||||
|
||||
assetRepo
|
||||
.findById(assetId)
|
||||
.ifPresent(assetRepo::delete);
|
||||
.findById(assetId)
|
||||
.ifPresent(assetRepo::delete);
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"The objectId is expected to start with 'folder-' or 'asset-'.");
|
||||
"The objectId is expected to start with 'folder-' or 'asset-'.");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -457,15 +461,15 @@ public class AssetFolderBrowserController {
|
|||
row.setObjectUuid(folder.getUuid());
|
||||
row.setName(folder.getName());
|
||||
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;
|
||||
}
|
||||
|
|
@ -478,14 +482,22 @@ public class AssetFolderBrowserController {
|
|||
row.setObjectUuid(asset.getUuid());
|
||||
row.setName(asset.getDisplayName());
|
||||
if (asset.getTitle().hasValue(globalizationHelper
|
||||
.getNegotiatedLocale())) {
|
||||
.getNegotiatedLocale())) {
|
||||
row.setTitle(asset.getTitle().getValue(globalizationHelper
|
||||
.getNegotiatedLocale()));
|
||||
.getNegotiatedLocale()));
|
||||
} else {
|
||||
row.setTitle(asset.getTitle().getValue(defaultLocale));
|
||||
}
|
||||
if (asset instanceof Image) {
|
||||
row.setThumbnailUrl(String
|
||||
.format("%s/content-sections/%s/images/"
|
||||
+ "uuid-%s?width=150&height=100",
|
||||
CCMDispatcherServlet.getContextPath(),
|
||||
CMS.getContext().getContentSection().getLabel(),
|
||||
asset.getUuid()));
|
||||
}
|
||||
final AssetTypeInfo typeInfo = typesManager
|
||||
.getAssetTypeInfo(asset.getClass());
|
||||
.getAssetTypeInfo(asset.getClass());
|
||||
row.setTypeLabelBundle(typeInfo.getLabelBundle());
|
||||
row.setTypeLabelKey(typeInfo.getLabelKey());
|
||||
|
||||
|
|
@ -506,32 +518,32 @@ public class AssetFolderBrowserController {
|
|||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
|
||||
final CriteriaQuery<Folder> criteria = builder
|
||||
.createQuery(Folder.class);
|
||||
.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)) {
|
||||
&& AssetFolderBrowser.SORT_ACTION_DOWN.
|
||||
equals(orderDirection)) {
|
||||
order = builder.desc(from.get("name"));
|
||||
} else {
|
||||
order = builder.asc(from.get("name"));
|
||||
}
|
||||
|
||||
final TypedQuery<Folder> query = entityManager
|
||||
.createQuery(
|
||||
criteria.where(
|
||||
builder.and(
|
||||
builder.
|
||||
equal(from.get("parentCategory"),
|
||||
folder),
|
||||
builder.like(builder.lower(from.get(
|
||||
"name")),
|
||||
filterTerm)
|
||||
)
|
||||
)
|
||||
.orderBy(order)
|
||||
);
|
||||
.createQuery(
|
||||
criteria.where(
|
||||
builder.and(
|
||||
builder.
|
||||
equal(from.get("parentCategory"),
|
||||
folder),
|
||||
builder.like(builder.lower(from.get(
|
||||
"name")),
|
||||
filterTerm)
|
||||
)
|
||||
)
|
||||
.orderBy(order)
|
||||
);
|
||||
|
||||
if (firstResult >= 0) {
|
||||
query.setFirstResult(firstResult);
|
||||
|
|
@ -582,35 +594,35 @@ public class AssetFolderBrowserController {
|
|||
|
||||
LOGGER.debug("The database contains {} assets.",
|
||||
entityManager.createQuery(criteria.select(fromAsset)
|
||||
.where(
|
||||
builder.and(
|
||||
builder.equal(join.get("category"),
|
||||
folder),
|
||||
builder.equal(join.get("type"),
|
||||
CmsConstants.CATEGORIZATION_TYPE_FOLDER),
|
||||
builder.like(builder.lower(
|
||||
fromAsset.get(
|
||||
"displayName")),
|
||||
filterTerm)
|
||||
))).getResultList().size());
|
||||
.where(
|
||||
builder.and(
|
||||
builder.equal(join.get("category"),
|
||||
folder),
|
||||
builder.equal(join.get("type"),
|
||||
CmsConstants.CATEGORIZATION_TYPE_FOLDER),
|
||||
builder.like(builder.lower(
|
||||
fromAsset.get(
|
||||
"displayName")),
|
||||
filterTerm)
|
||||
))).getResultList().size());
|
||||
|
||||
final TypedQuery<Asset> query = entityManager
|
||||
.createQuery(
|
||||
criteria.select(fromAsset)
|
||||
.where(
|
||||
builder.and(
|
||||
builder.equal(join.get(
|
||||
"category"), folder),
|
||||
builder.equal(join.get("type"),
|
||||
CmsConstants.CATEGORIZATION_TYPE_FOLDER),
|
||||
builder.like(builder.lower(
|
||||
fromAsset.get(
|
||||
"displayName")),
|
||||
filterTerm)
|
||||
)
|
||||
)
|
||||
.orderBy(order)
|
||||
);
|
||||
.createQuery(
|
||||
criteria.select(fromAsset)
|
||||
.where(
|
||||
builder.and(
|
||||
builder.equal(join.get(
|
||||
"category"), folder),
|
||||
builder.equal(join.get("type"),
|
||||
CmsConstants.CATEGORIZATION_TYPE_FOLDER),
|
||||
builder.like(builder.lower(
|
||||
fromAsset.get(
|
||||
"displayName")),
|
||||
filterTerm)
|
||||
)
|
||||
)
|
||||
.orderBy(order)
|
||||
);
|
||||
|
||||
if (firstResult >= 0) {
|
||||
query.setFirstResult(firstResult);
|
||||
|
|
|
|||
|
|
@ -35,9 +35,10 @@ class AssetFolderBrowserTableModel implements TableModel {
|
|||
protected static final int COL_NAME = 0;
|
||||
protected static final int COL_TITLE = 1;
|
||||
protected static final int COL_TYPE = 2;
|
||||
protected static final int COL_CREATION_DATE = 3;
|
||||
protected static final int COL_LAST_MODIFIED = 4;
|
||||
protected static final int COL_DELETEABLE = 5;
|
||||
protected static final int COL_THUMBNAIL = 3;
|
||||
protected static final int COL_CREATION_DATE = 4;
|
||||
protected static final int COL_LAST_MODIFIED = 5;
|
||||
protected static final int COL_DELETEABLE = 6;
|
||||
|
||||
private final Iterator<AssetFolderBrowserTableRow> iterator;
|
||||
private AssetFolderBrowserTableRow currentRow;
|
||||
|
|
@ -79,6 +80,8 @@ class AssetFolderBrowserTableModel implements TableModel {
|
|||
} else {
|
||||
return new GlobalizedMessage(typeLabelKey, typeLabelBundle);
|
||||
}
|
||||
case COL_THUMBNAIL:
|
||||
return currentRow.getThumbnailUrl();
|
||||
case COL_CREATION_DATE:
|
||||
return currentRow.getCreated();
|
||||
case COL_LAST_MODIFIED:
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ class AssetFolderBrowserTableRow {
|
|||
private String objectUuid;
|
||||
private String name;
|
||||
private String title;
|
||||
private String thumbnailUrl;
|
||||
private String typeLabelBundle;
|
||||
private String typeLabelKey;
|
||||
private Date created;
|
||||
|
|
@ -68,6 +69,14 @@ class AssetFolderBrowserTableRow {
|
|||
public void setTitle(final String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getThumbnailUrl() {
|
||||
return thumbnailUrl;
|
||||
}
|
||||
|
||||
public void setThumbnailUrl(final String thumbnailUrl) {
|
||||
this.thumbnailUrl = thumbnailUrl;
|
||||
}
|
||||
|
||||
public String getTypeLabelBundle() {
|
||||
return typeLabelBundle;
|
||||
|
|
|
|||
|
|
@ -62,6 +62,76 @@ public class Images {
|
|||
@Inject
|
||||
private AssetRepository assetRepo;
|
||||
|
||||
@GET
|
||||
@Path("/uuid-{uuid}")
|
||||
public Response getImageByUuid(
|
||||
@PathParam("content-section")
|
||||
final String sectionName,
|
||||
@PathParam("uuid")
|
||||
final String uuid,
|
||||
@QueryParam("width")
|
||||
@DefaultValue("-1")
|
||||
final String widthParam,
|
||||
@QueryParam("height")
|
||||
@DefaultValue("-1")
|
||||
final String heightParam) {
|
||||
|
||||
final Optional<Asset> asset = assetRepo
|
||||
.findByUuidAndType(uuid, Image.class);
|
||||
|
||||
if (asset.isPresent()) {
|
||||
if (asset.get() instanceof Image) {
|
||||
return loadImage((Image) asset.get(), widthParam, heightParam);
|
||||
} else {
|
||||
return Response
|
||||
.status(Response.Status.NOT_FOUND)
|
||||
.entity(String
|
||||
.format("The asset with the requested UUID \"%s\" "
|
||||
+ "is not an image.",
|
||||
uuid))
|
||||
.build();
|
||||
}
|
||||
} else {
|
||||
return Response
|
||||
.status(Response.Status.NOT_FOUND)
|
||||
.entity(String
|
||||
.format("The requested image \"%s\" does not exist.",
|
||||
uuid))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/uuid-{uuid}/properties")
|
||||
public Response getImagePropertiesByUuid(
|
||||
@PathParam("content-section") final String sectionName,
|
||||
@PathParam("uuid") final String uuid) {
|
||||
|
||||
final Optional<Asset> asset = assetRepo.findByUuidAndType(uuid,
|
||||
Image.class);
|
||||
|
||||
if (asset.isPresent()) {
|
||||
if (asset.get() instanceof Image) {
|
||||
return readImageProperties((Image) asset.get());
|
||||
} else {
|
||||
return Response
|
||||
.status(Response.Status.NOT_FOUND)
|
||||
.entity(String
|
||||
.format("The asset with the requested UUID \"%s\" "
|
||||
+ "is not an image.",
|
||||
uuid))
|
||||
.build();
|
||||
}
|
||||
} else {
|
||||
return Response
|
||||
.status(Response.Status.NOT_FOUND)
|
||||
.entity(String
|
||||
.format("The requested image \"%s\" does not exist.",
|
||||
uuid))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the image requested by the provided content section and path.
|
||||
*
|
||||
|
|
@ -119,80 +189,7 @@ public class Images {
|
|||
|
||||
if (asset.isPresent()) {
|
||||
if (asset.get() instanceof Image) {
|
||||
final Image image = (Image) asset.get();
|
||||
final byte[] data = image.getData();
|
||||
final String mimeType = image.getMimeType().toString();
|
||||
|
||||
final InputStream inputStream = new ByteArrayInputStream(data);
|
||||
final BufferedImage bufferedImage;
|
||||
final String imageFormat;
|
||||
try {
|
||||
final ImageInputStream imageInputStream = ImageIO
|
||||
.createImageInputStream(inputStream);
|
||||
final Iterator<ImageReader> readers = ImageIO
|
||||
.getImageReaders(imageInputStream);
|
||||
final ImageReader imageReader;
|
||||
if (readers.hasNext()) {
|
||||
imageReader = readers.next();
|
||||
} else {
|
||||
LOGGER.error("No image reader for image {} (UUID: {}) "
|
||||
+ "available.",
|
||||
image.getDisplayName(),
|
||||
image.getUuid());
|
||||
return Response.serverError().build();
|
||||
}
|
||||
imageReader.setInput(imageInputStream);
|
||||
bufferedImage = imageReader.read(0);
|
||||
imageFormat = imageReader.getFormatName();
|
||||
} catch (IOException ex) {
|
||||
LOGGER.error("Failed to load image {} (UUID: {}).",
|
||||
image.getDisplayName(),
|
||||
image.getUuid());
|
||||
LOGGER.error(ex);
|
||||
return Response.serverError().build();
|
||||
}
|
||||
|
||||
// Yes, this is correct. The parameters provided in the URL
|
||||
// are expected to be integers. The private scaleImage method
|
||||
// works with floats to be accurate (divisions are performed
|
||||
// with the values for width and height)
|
||||
final int width = parseScaleParameter(widthParam, "width");
|
||||
final int height = parseScaleParameter(heightParam, "height");
|
||||
final java.awt.Image scaledImage = scaleImage(bufferedImage,
|
||||
width,
|
||||
height);
|
||||
|
||||
final ByteArrayOutputStream outputStream
|
||||
= new ByteArrayOutputStream();
|
||||
final BufferedImage bufferedScaledImage = new BufferedImage(
|
||||
scaledImage.getWidth(null),
|
||||
scaledImage.getHeight(null),
|
||||
bufferedImage.getType());
|
||||
bufferedScaledImage
|
||||
.getGraphics()
|
||||
.drawImage(scaledImage, 0, 0, null);
|
||||
try {
|
||||
ImageIO
|
||||
.write(bufferedScaledImage, imageFormat, outputStream);
|
||||
} catch (IOException ex) {
|
||||
LOGGER.error("Failed to render scaled variant of image {} "
|
||||
+ "(UUID: {}).",
|
||||
image.getDisplayName(),
|
||||
image.getUuid());
|
||||
LOGGER.error(ex);
|
||||
return Response.serverError().build();
|
||||
}
|
||||
|
||||
// return Response
|
||||
// .ok(String.format(
|
||||
// "Requested image \"%s\" in content section \"%s\"",
|
||||
// path,
|
||||
// section.get().getLabel()),
|
||||
// "text/plain")
|
||||
// .build();
|
||||
return Response
|
||||
.ok(outputStream.toByteArray(), mimeType)
|
||||
.build();
|
||||
return loadImage((Image) asset.get(), widthParam, heightParam);
|
||||
} else {
|
||||
return Response
|
||||
.status(Response.Status.NOT_FOUND)
|
||||
|
|
@ -210,16 +207,6 @@ public class Images {
|
|||
path))
|
||||
.build();
|
||||
}
|
||||
|
||||
// final Response.ResponseBuilder builder = Response
|
||||
// .ok(String.format(
|
||||
// "Requested image \"%s\" from folder \"%s\" in content section \"%s\"",
|
||||
// imageName,
|
||||
// folderPath,
|
||||
// section.get().getLabel()),
|
||||
// "text/plain");
|
||||
//
|
||||
// return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -253,39 +240,7 @@ public class Images {
|
|||
|
||||
if (asset.isPresent()) {
|
||||
if (asset.get() instanceof Image) {
|
||||
final Image image = (Image) asset.get();
|
||||
final byte[] data = image.getData();
|
||||
final String mimeType = image.getMimeType().toString();
|
||||
|
||||
final InputStream inputStream = new ByteArrayInputStream(data);
|
||||
final BufferedImage bufferedImage;
|
||||
try {
|
||||
bufferedImage = ImageIO.read(inputStream);
|
||||
} catch (IOException ex) {
|
||||
LOGGER.error("Failed to load image {} (UUID: {}).",
|
||||
image.getDisplayName(),
|
||||
image.getUuid());
|
||||
LOGGER.error(ex);
|
||||
return Response.serverError().build();
|
||||
}
|
||||
|
||||
final String imageProperties = String
|
||||
.format("{%n"
|
||||
+ " \"name\": \"%s\",%n"
|
||||
+ " \"filename\": \"%s\",%n"
|
||||
+ " \"mimetype\": \"%s\",%n"
|
||||
+ " \"width\": %d,%n"
|
||||
+ " \"height\": %d%n"
|
||||
+ "}",
|
||||
image.getDisplayName(),
|
||||
image.getFileName(),
|
||||
mimeType,
|
||||
bufferedImage.getWidth(),
|
||||
bufferedImage.getHeight());
|
||||
|
||||
return Response
|
||||
.ok(imageProperties, "application/json")
|
||||
.build();
|
||||
return readImageProperties((Image) asset.get());
|
||||
} else {
|
||||
return Response
|
||||
.status(Response.Status.NOT_FOUND)
|
||||
|
|
@ -305,6 +260,134 @@ public class Images {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for loading the image from the {@link Image} asset entity.
|
||||
*
|
||||
* This method also does the scaling of the image.
|
||||
*
|
||||
* @param image The image asset containing the image.
|
||||
* @param widthParam The value of the width parameter.
|
||||
* @param heightParam The value of the height parameter.
|
||||
*
|
||||
* @return The {@link Response} for sending the (scaled) image to the
|
||||
* requesting user agent.
|
||||
*/
|
||||
private Response loadImage(final Image image,
|
||||
final String widthParam,
|
||||
final String heightParam) {
|
||||
|
||||
final byte[] data = image.getData();
|
||||
final String mimeType = image.getMimeType().toString();
|
||||
|
||||
final InputStream inputStream = new ByteArrayInputStream(data);
|
||||
final BufferedImage bufferedImage;
|
||||
final String imageFormat;
|
||||
try {
|
||||
final ImageInputStream imageInputStream = ImageIO
|
||||
.createImageInputStream(inputStream);
|
||||
final Iterator<ImageReader> readers = ImageIO
|
||||
.getImageReaders(imageInputStream);
|
||||
final ImageReader imageReader;
|
||||
if (readers.hasNext()) {
|
||||
imageReader = readers.next();
|
||||
} else {
|
||||
LOGGER.error("No image reader for image {} (UUID: {}) "
|
||||
+ "available.",
|
||||
image.getDisplayName(),
|
||||
image.getUuid());
|
||||
return Response.serverError().build();
|
||||
}
|
||||
imageReader.setInput(imageInputStream);
|
||||
bufferedImage = imageReader.read(0);
|
||||
imageFormat = imageReader.getFormatName();
|
||||
} catch (IOException ex) {
|
||||
LOGGER.error("Failed to load image {} (UUID: {}).",
|
||||
image.getDisplayName(),
|
||||
image.getUuid());
|
||||
LOGGER.error(ex);
|
||||
return Response.serverError().build();
|
||||
}
|
||||
|
||||
// Yes, this is correct. The parameters provided in the URL
|
||||
// are expected to be integers. The private scaleImage method
|
||||
// works with floats to be accurate (divisions are performed
|
||||
// with the values for width and height)
|
||||
final int width = parseScaleParameter(widthParam, "width");
|
||||
final int height = parseScaleParameter(heightParam, "height");
|
||||
final java.awt.Image scaledImage = scaleImage(bufferedImage,
|
||||
width,
|
||||
height);
|
||||
|
||||
final ByteArrayOutputStream outputStream
|
||||
= new ByteArrayOutputStream();
|
||||
final BufferedImage bufferedScaledImage = new BufferedImage(
|
||||
scaledImage.getWidth(null),
|
||||
scaledImage.getHeight(null),
|
||||
bufferedImage.getType());
|
||||
bufferedScaledImage
|
||||
.getGraphics()
|
||||
.drawImage(scaledImage, 0, 0, null);
|
||||
try {
|
||||
ImageIO
|
||||
.write(bufferedScaledImage, imageFormat, outputStream);
|
||||
} catch (IOException ex) {
|
||||
LOGGER.error("Failed to render scaled variant of image {} "
|
||||
+ "(UUID: {}).",
|
||||
image.getDisplayName(),
|
||||
image.getUuid());
|
||||
LOGGER.error(ex);
|
||||
return Response.serverError().build();
|
||||
}
|
||||
|
||||
return Response
|
||||
.ok(outputStream.toByteArray(), mimeType)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for reading the image properties and converting them into
|
||||
* an JSON response.
|
||||
*
|
||||
* @param image The image which properties are read.
|
||||
*
|
||||
* @return A {@link Response} with the image properties as JSON.
|
||||
*/
|
||||
private Response readImageProperties(final Image image) {
|
||||
|
||||
final byte[] data = image.getData();
|
||||
final String mimeType = image.getMimeType().toString();
|
||||
|
||||
final InputStream inputStream = new ByteArrayInputStream(data);
|
||||
final BufferedImage bufferedImage;
|
||||
try {
|
||||
bufferedImage = ImageIO.read(inputStream);
|
||||
} catch (IOException ex) {
|
||||
LOGGER.error("Failed to load image {} (UUID: {}).",
|
||||
image.getDisplayName(),
|
||||
image.getUuid());
|
||||
LOGGER.error(ex);
|
||||
return Response.serverError().build();
|
||||
}
|
||||
|
||||
final String imageProperties = String
|
||||
.format("{%n"
|
||||
+ " \"name\": \"%s\",%n"
|
||||
+ " \"filename\": \"%s\",%n"
|
||||
+ " \"mimetype\": \"%s\",%n"
|
||||
+ " \"width\": %d,%n"
|
||||
+ " \"height\": %d%n"
|
||||
+ "}",
|
||||
image.getDisplayName(),
|
||||
image.getFileName(),
|
||||
mimeType,
|
||||
bufferedImage.getWidth(),
|
||||
bufferedImage.getHeight());
|
||||
|
||||
return Response
|
||||
.ok(imageProperties, "application/json")
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for parsing the parameters for scaling an image into
|
||||
* integers.
|
||||
|
|
|
|||
|
|
@ -386,3 +386,4 @@ related_info_step_description=Add related information
|
|||
cms.ui.authoring.file_upload.auto_detect=(Auto-Detect)
|
||||
cms.ui.upload_new_content=Upload new content
|
||||
cms.ui.asset.name=Name
|
||||
cms.ui.asset.thumbnail=Preview
|
||||
|
|
|
|||
|
|
@ -383,3 +383,4 @@ related_info_step_description=Weiterf\u00fchrende Informationen hinzuf\u00fcgen
|
|||
cms.ui.authoring.file_upload.auto_detect=(Automatisch erkennen)
|
||||
cms.ui.upload_new_content=Neuen Inhalt hochladen
|
||||
cms.ui.asset.name=Name
|
||||
cms.ui.asset.thumbnail=Vorschau
|
||||
|
|
|
|||
|
|
@ -342,3 +342,4 @@ related_info_step_description=Add related information
|
|||
cms.ui.authoring.file_upload.auto_detect=(Auto-Detect)
|
||||
cms.ui.upload_new_content=Upload new content
|
||||
cms.ui.asset.name=Name
|
||||
cms.ui.asset.thumbnail=Preview
|
||||
|
|
|
|||
|
|
@ -52,9 +52,12 @@ import javax.servlet.http.HttpServletResponse;
|
|||
import javax.servlet.jsp.PageContext;
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import javax.servlet.ServletRequestWrapper;
|
||||
|
||||
/**
|
||||
* Class static helper methods for request dispatching. Contains various
|
||||
* generally useful procedural abstractions.
|
||||
|
|
@ -70,7 +73,8 @@ public final class DispatcherHelper implements DispatcherConstants {
|
|||
* set com.arsdigita.dispatcher.DispatcherHelper=DEBUG by uncommenting or
|
||||
* adding the line.
|
||||
*/
|
||||
private static final Logger LOGGER = LogManager.getLogger(DispatcherHelper.class);
|
||||
private static final Logger LOGGER = LogManager.getLogger(
|
||||
DispatcherHelper.class);
|
||||
private static String s_webappCtx;
|
||||
private static String s_staticURL;
|
||||
private static boolean s_cachingActive;
|
||||
|
|
@ -177,7 +181,14 @@ public final class DispatcherHelper implements DispatcherConstants {
|
|||
}
|
||||
|
||||
public static String getDispatcherPrefix(HttpServletRequest req) {
|
||||
return (String) req.getAttribute(DISPATCHER_PREFIX_ATTR);
|
||||
final HttpServletRequest request;
|
||||
if (req instanceof ShiroHttpServletRequest) {
|
||||
request = (HttpServletRequest) ((ServletRequestWrapper) req)
|
||||
.getRequest();
|
||||
} else {
|
||||
request = req;
|
||||
}
|
||||
return (String) request.getAttribute(DISPATCHER_PREFIX_ATTR);
|
||||
}
|
||||
|
||||
public static void setDispatcherPrefix(HttpServletRequest req,
|
||||
|
|
@ -541,10 +552,10 @@ public final class DispatcherHelper implements DispatcherConstants {
|
|||
|
||||
if (previous instanceof MultipartHttpServletRequest) {
|
||||
LOGGER.debug("Build new multipart request from previous "
|
||||
+ previous + " and current " + orig);
|
||||
+ previous + " and current " + orig);
|
||||
|
||||
MultipartHttpServletRequest previousmp
|
||||
= (MultipartHttpServletRequest) previous;
|
||||
= (MultipartHttpServletRequest) previous;
|
||||
|
||||
sreq = new MultipartHttpServletRequest(previousmp,
|
||||
orig);
|
||||
|
|
@ -567,7 +578,7 @@ public final class DispatcherHelper implements DispatcherConstants {
|
|||
}
|
||||
} else {
|
||||
LOGGER.debug("The request is not multipart; proceeding "
|
||||
+ "without wrapping the request");
|
||||
+ "without wrapping the request");
|
||||
}
|
||||
return sreq;
|
||||
}
|
||||
|
|
@ -681,14 +692,14 @@ public final class DispatcherHelper implements DispatcherConstants {
|
|||
destination = URL.there(req, url.substring(0, sep), params);
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Setting destination with map to "
|
||||
+ destination);
|
||||
+ destination);
|
||||
}
|
||||
}
|
||||
throw new RedirectSignal(destination, true);
|
||||
} else {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Redirecting to URL without using URL.there. "
|
||||
+ "URL is " + url);
|
||||
+ "URL is " + url);
|
||||
}
|
||||
throw new RedirectSignal(url, true);
|
||||
}
|
||||
|
|
@ -875,7 +886,7 @@ public final class DispatcherHelper implements DispatcherConstants {
|
|||
LOGGER.warn(
|
||||
"webappContext changed. Expected='" + s_webappCtx
|
||||
+ "' found='" + webappCtx
|
||||
+ "'.\nPerhaps the enterprise.init "
|
||||
+ "'.\nPerhaps the enterprise.init "
|
||||
+ "com.arsdigita.dispatcher.Initializer webappContext "
|
||||
+ "parameter is wrong.");
|
||||
// Save the webappCtx from the request for future use.
|
||||
|
|
@ -1193,7 +1204,7 @@ public final class DispatcherHelper implements DispatcherConstants {
|
|||
// Set the preferedLocale to the default locale (first entry in the
|
||||
// config parameter list)
|
||||
Locale preferedLocale
|
||||
= new Locale(kernelConfig.getDefaultLanguage(), "", "");
|
||||
= new Locale(kernelConfig.getDefaultLanguage(), "", "");
|
||||
|
||||
// The ACCEPTED_LANGUAGES from the client
|
||||
Enumeration locales = null;
|
||||
|
|
|
|||
|
|
@ -706,7 +706,7 @@ public class URL {
|
|||
@SuppressWarnings("unchecked")
|
||||
final Bean<ConfigurationManager> bean
|
||||
= (Bean<ConfigurationManager>) iterator
|
||||
.next();
|
||||
.next();
|
||||
final CreationalContext<ConfigurationManager> ctx = beanManager
|
||||
.createCreationalContext(bean);
|
||||
confManager = (ConfigurationManager) beanManager.getReference(
|
||||
|
|
|
|||
Loading…
Reference in New Issue