001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (https://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software, please see the
018 * company website: https://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: https://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.ui.util;
029
030import org.opencms.file.CmsResource;
031import org.opencms.file.types.CmsResourceTypeImage;
032import org.opencms.main.CmsPermalinkResourceHandler;
033import org.opencms.main.OpenCms;
034import org.opencms.ui.CmsCssIcon;
035import org.opencms.ui.components.OpenCmsTheme;
036import org.opencms.util.CmsStringUtil;
037import org.opencms.workplace.explorer.CmsResourceUtil;
038
039import com.vaadin.server.ExternalResource;
040import com.vaadin.shared.ui.ContentMode;
041import com.vaadin.ui.Component;
042import com.vaadin.ui.Label;
043import com.vaadin.ui.Link;
044
045/**
046 * Creates clickable previews for images and other files.
047 */
048public final class CmsGalleryFilePreview {
049
050    /** The height of the preview images. */
051    public static final int IMAGE_HEIGHT = 170;
052
053    /** The width of the preview images. */
054    public static final int IMAGE_WIDTH = 200;
055
056    /**
057     * Creates a clickable file preview.
058     * @param resource the resource to create the preview for
059     * @return the clickable file preview
060     */
061    public static Component createClickableFile(CmsResource resource) {
062
063        CmsResourceUtil resourceUtil = new CmsResourceUtil(resource);
064        return createClickableFile(resource, resourceUtil);
065    }
066
067    /**
068     * Creates a clickable file preview.<p>
069     * @param resource the resource to create the preview for
070     * @param resourceUtil the resource util
071     *
072     * @return the clickable file preview
073     */
074    public static Component createClickableFile(CmsResource resource, CmsResourceUtil resourceUtil) {
075
076        Component preview = (resource == null) || isTypeImage(resource)
077        ? createClickableImage(resource)
078        : createClickableOther(resource, resourceUtil);
079        preview.setWidth(IMAGE_WIDTH + "px");
080        preview.setHeight(IMAGE_HEIGHT + "px");
081        return preview;
082    }
083
084    /**
085     * Gets the scaling query string for the preview.
086     * @param highres if true, generates high-resolution scaling query string
087     * @return the scaling parameters
088     */
089    public static String getScaleQueryString(boolean highres) {
090
091        return "?__scale=" + getScaleParameter(highres);
092    }
093
094    /**
095     * Utility function to create a clickable image.<p>
096     * @param resource the resource
097     *
098     * @return the clickable image
099     */
100    private static Label createClickableImage(CmsResource resource) {
101
102        String scaleUri = resource == null ? "#" : CmsGalleryFilePreview.getScaleUri(resource, false);
103        String permanentUri = resource == null ? "#" : CmsGalleryFilePreview.getPermanentUri(resource);
104        String image = "<img width=\""
105            + IMAGE_WIDTH
106            + "px\" height=\""
107            + IMAGE_HEIGHT
108            + "px\" src=\""
109            + scaleUri
110            + "\""
111            + " srcset=\""
112            + scaleUri
113            + " 2x"
114            + "\" "
115            + " onerror='cmsJsFunctions.handleBrokenImage(this)' "
116            + " >";
117        String a = "<a target=\"_blank\" href=\"" + permanentUri + "\">" + image + "</a>";
118        String div = "<div class=\""
119            + OpenCmsTheme.GALLERY_PREVIEW_IMAGE
120            + "\" style=\"width:"
121            + IMAGE_WIDTH
122            + "px;height:"
123            + IMAGE_HEIGHT
124            + "px;\">"
125            + a
126            + "</div>";
127        Label label = new Label(div);
128        label.setContentMode(ContentMode.HTML);
129        return label;
130    }
131
132    /**
133     * Utility function to create a clickable preview for files that are not images.
134     * @param resource the resource
135     * @param resourceUtil the resource util
136     *
137     * @return the clickable preview
138     */
139    private static Link createClickableOther(CmsResource resource, CmsResourceUtil resourceUtil) {
140
141        CmsCssIcon cssIcon = (CmsCssIcon)resourceUtil.getSmallIconResource();
142        String caption = "<div style=\"width:"
143            + IMAGE_WIDTH
144            + "px;height:"
145            + IMAGE_HEIGHT
146            + "px;display: flex; justify-content: center; align-items: center;\"><span class=\""
147            + cssIcon.getStyleName()
148            + "\" style=\"transform: scale(4);\"></span></div>";
149        Link link = new Link(caption, new ExternalResource(CmsGalleryFilePreview.getPermanentUri(resource)));
150        link.setCaptionAsHtml(true);
151        link.setTargetName("_blank");
152        return link;
153    }
154
155    /**
156     * Creates a permanent URI for a file preview.<p>
157     *
158     * @param resource the CMS resource
159     * @return the permanent URI
160     */
161    private static String getPermanentUri(CmsResource resource) {
162
163        String structureId = resource.getStructureId().toString();
164        String extension = CmsResource.getExtension(resource.getRootPath());
165        String suffix = (extension != null) ? "." + extension : "";
166        String permalink = CmsStringUtil.joinPaths(
167            OpenCms.getSystemInfo().getOpenCmsContext(),
168            CmsPermalinkResourceHandler.PERMALINK_HANDLER,
169            structureId) + suffix;
170        return permalink;
171    }
172
173    /**
174     * Gets the scaling parameters for the preview.
175     *
176     * @param highres if true, generates high-resolution scaling parameters
177     * @return the scaling parameters
178     */
179    private static String getScaleParameter(boolean highres) {
180
181        int m = highres ? 2 : 1;
182        String suffix = highres ? ",q:85" : "";
183        return "t:9,w:" + (m * IMAGE_WIDTH) + ",h:" + (m * IMAGE_HEIGHT) + suffix;
184
185    }
186
187    /**
188     * Creates a permanent URI for a scaled preview image.<p>
189     *
190     * @param resource the CMS resource
191     * @param highres if true, generate high resolution scaling uri
192     * @return the scale URI
193     */
194    private static String getScaleUri(CmsResource resource, boolean highres) {
195
196        String paramTimestamp = "&timestamp=" + System.currentTimeMillis();
197        return getPermanentUri(resource) + getScaleQueryString(highres) + paramTimestamp;
198    }
199
200    /**
201     * Returns whether the actual resource is an image.
202     * @param resource the resource
203     * @return whether the actual resource is an image
204     */
205    private static boolean isTypeImage(CmsResource resource) {
206
207        return OpenCms.getResourceManager().getResourceType(resource) instanceof CmsResourceTypeImage;
208    }
209}