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
parent
f1c033c307
commit
f7d7293868
|
|
@ -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.*;
|
||||
|
||||
|
|
@ -484,6 +488,14 @@ public class AssetFolderBrowserController {
|
|||
} 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());
|
||||
row.setTypeLabelBundle(typeInfo.getLabelBundle());
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -69,6 +70,14 @@ class AssetFolderBrowserTableRow {
|
|||
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,7 +189,93 @@ public class Images {
|
|||
|
||||
if (asset.isPresent()) {
|
||||
if (asset.get() instanceof Image) {
|
||||
final Image image = (Image) asset.get();
|
||||
return loadImage((Image) asset.get(), widthParam, heightParam);
|
||||
} else {
|
||||
return Response
|
||||
.status(Response.Status.NOT_FOUND)
|
||||
.entity(String
|
||||
.format("The asset found at the requested path \"%s\" "
|
||||
+ "is not an image.",
|
||||
path))
|
||||
.build();
|
||||
}
|
||||
} else {
|
||||
return Response
|
||||
.status(Response.Status.NOT_FOUND)
|
||||
.entity(String
|
||||
.format("The requested image \"%s\" does not exist.",
|
||||
path))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides several properties of an image to a user agent as JSON.
|
||||
*
|
||||
* @param sectionName The name of the content section which contains the
|
||||
* image.
|
||||
* @param path The path to the image.
|
||||
*
|
||||
* @return A {@link Response} with the informations about the requested
|
||||
* image.
|
||||
*/
|
||||
@GET
|
||||
@Path("/{path:.*}/properties")
|
||||
public Response getImageProperties(
|
||||
@PathParam("content-section") final String sectionName,
|
||||
@PathParam("path") final String path) {
|
||||
|
||||
final Optional<ContentSection> section = sectionRepo
|
||||
.findByLabel(sectionName);
|
||||
if (!section.isPresent()) {
|
||||
return Response
|
||||
.status(Response.Status.NOT_FOUND)
|
||||
.entity(String.format("No content section \"%s\" available.",
|
||||
sectionName))
|
||||
.build();
|
||||
}
|
||||
|
||||
final Optional<Asset> asset = assetRepo.findByPath(section.get(),
|
||||
path);
|
||||
|
||||
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 found at the requested path \"%s\" "
|
||||
+ "is not an image.",
|
||||
path))
|
||||
.build();
|
||||
}
|
||||
} else {
|
||||
return Response
|
||||
.status(Response.Status.NOT_FOUND)
|
||||
.entity(String
|
||||
.format("The requested image \"%s\" does not exist.",
|
||||
path))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
|
|
@ -183,77 +339,21 @@ public class Images {
|
|||
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();
|
||||
} else {
|
||||
return Response
|
||||
.status(Response.Status.NOT_FOUND)
|
||||
.entity(String
|
||||
.format("The asset found at the requested path \"%s\" "
|
||||
+ "is not an image.",
|
||||
path))
|
||||
.build();
|
||||
}
|
||||
} else {
|
||||
return Response
|
||||
.status(Response.Status.NOT_FOUND)
|
||||
.entity(String
|
||||
.format("The requested image \"%s\" does not exist.",
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides several properties of an image to a user agent as JSON.
|
||||
* Helper method for reading the image properties and converting them into
|
||||
* an JSON response.
|
||||
*
|
||||
* @param sectionName The name of the content section which contains the
|
||||
* image.
|
||||
* @param path The path to the image.
|
||||
* @param image The image which properties are read.
|
||||
*
|
||||
* @return A {@link Response} with the informations about the requested
|
||||
* image.
|
||||
* @return A {@link Response} with the image properties as JSON.
|
||||
*/
|
||||
@GET
|
||||
@Path("/{path:.*}/properties")
|
||||
public Response getImageProperties(
|
||||
@PathParam("content-section") final String sectionName,
|
||||
@PathParam("path") final String path) {
|
||||
private Response readImageProperties(final Image image) {
|
||||
|
||||
final Optional<ContentSection> section = sectionRepo
|
||||
.findByLabel(sectionName);
|
||||
if (!section.isPresent()) {
|
||||
return Response
|
||||
.status(Response.Status.NOT_FOUND)
|
||||
.entity(String.format("No content section \"%s\" available.",
|
||||
sectionName))
|
||||
.build();
|
||||
}
|
||||
|
||||
final Optional<Asset> asset = assetRepo.findByPath(section.get(),
|
||||
path);
|
||||
|
||||
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();
|
||||
|
||||
|
|
@ -286,23 +386,6 @@ public class Images {
|
|||
return Response
|
||||
.ok(imageProperties, "application/json")
|
||||
.build();
|
||||
} else {
|
||||
return Response
|
||||
.status(Response.Status.NOT_FOUND)
|
||||
.entity(String
|
||||
.format("The asset found at the requested path \"%s\" "
|
||||
+ "is not an image.",
|
||||
path))
|
||||
.build();
|
||||
}
|
||||
} else {
|
||||
return Response
|
||||
.status(Response.Status.NOT_FOUND)
|
||||
.entity(String
|
||||
.format("The requested image \"%s\" does not exist.",
|
||||
path))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue