All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.mklinger.qetcher.liferay.client.impl.abstraction.DLToolImpl Maven / Gradle / Ivy

/*
 * Copyright 2013-present mklinger GmbH - http://www.mklinger.de
 *
 * All rights reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of mklinger GmbH and its suppliers, if any.
 * The intellectual and technical concepts contained herein are
 * proprietary to mklinger GmbH and its suppliers and are protected
 * by trade secret or copyright law. Dissemination of this
 * information or reproduction of this material is strictly forbidden
 * unless prior written permission is obtained from mklinger GmbH.
 */
package de.mklinger.qetcher.liferay.client.impl.abstraction;

import java.awt.image.RenderedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLDecoder;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.liferay.portal.kernel.image.ImageBag;
import com.liferay.portal.kernel.image.ImageToolUtil;
import com.liferay.portal.kernel.repository.model.FileEntry;
import com.liferay.portal.kernel.util.DocumentConversionUtil;
import com.liferay.portal.kernel.util.FileUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.HttpUtil;
import com.liferay.portal.kernel.util.MimeTypesUtil;
import com.liferay.portal.kernel.util.PropsKeys;
import com.liferay.portal.kernel.util.PropsUtil;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.model.Company;
import com.liferay.portal.model.ImageConstants;
import com.liferay.portal.model.User;
import com.liferay.portal.security.auth.CompanyThreadLocal;
import com.liferay.portal.security.auth.PrincipalThreadLocal;
import com.liferay.portal.security.permission.PermissionThreadLocal;
import com.liferay.portal.service.CompanyLocalServiceUtil;
import com.liferay.portal.service.UserLocalServiceUtil;
import com.liferay.portlet.documentlibrary.NoSuchFileEntryException;
import com.liferay.portlet.documentlibrary.model.DLFileShortcut;
import com.liferay.portlet.documentlibrary.service.DLAppServiceUtil;
import com.liferay.portlet.documentlibrary.util.DLPreviewableProcessor;
import com.liferay.portlet.documentlibrary.util.DLUtil;
import com.liferay.portlet.documentlibrary.util.ImageProcessorUtil;
import com.liferay.portlet.documentlibrary.util.PDFProcessor;
import com.liferay.portlet.documentlibrary.util.PDFProcessorUtil;

import de.mklinger.qetcher.liferay.abstraction.DLTool;
import de.mklinger.qetcher.liferay.abstraction.DocumentLibraryFileContents;
import de.mklinger.qetcher.liferay.abstraction.FileVersion;
import de.mklinger.qetcher.liferay.abstraction.Image;
import de.mklinger.qetcher.liferay.abstraction.LiferayException;

/**
 * @author Marc Klinger - mklinger[at]mklinger[dot]de
 */
public class DLToolImpl implements DLTool {
	private static final Logger LOG = LoggerFactory.getLogger(DLToolImpl.class);

	@Override
	public String getPreviewPath() {
		return DLPreviewableProcessor.PREVIEW_PATH;
	}

	@Override
	public DocumentLibraryFileContents getDocumentLibraryFileContents(final URI uri) {
		try {
			final Long companyId = CompanyThreadLocal.getCompanyId();
			if (companyId == null || companyId <= 0) {
				return null;
			}
			final Company company = CompanyLocalServiceUtil.getCompany(companyId);

			if (!uri.getHost().equals(company.getVirtualHostname())) {
				return null;
			}

			if (!uri.getPath().startsWith("/documents/") && !uri.getPath().startsWith("/image/")) {
				return null;
			}

			return doGetDocumentLibraryFileContents(uri);

		} catch (final Exception e) {
			LOG.warn("Error getting document library file contents", e);
			return null;
		}
	}

	/** See com.liferay.portal.webserver.WebServerServlet.service(HttpServletRequest, HttpServletResponse) */
	private DocumentLibraryFileContents doGetDocumentLibraryFileContents(final URI uri) throws Exception {
		LOG.debug("Current user: {} - '{}'", PrincipalThreadLocal.getUserId(), PrincipalThreadLocal.getName());
		LOG.debug("Current permission checker: {}", PermissionThreadLocal.getPermissionChecker());

		//        user = _getUser(request);
		//
		//        PrincipalThreadLocal.setName(user.getUserId());
		//        PrincipalThreadLocal.setPassword(
		//            PortalUtil.getUserPassword(request));
		//
		//        PermissionChecker permissionChecker =
		//            PermissionCheckerFactoryUtil.create(user);
		//
		//        PermissionThreadLocal.setPermissionChecker(permissionChecker);


		final String[] pathArray = getPathArray(uri);
		if (pathArray == null) {
			return null;
		}

		final Map parameters = getParameters(uri);
		LOG.debug("Parameters: {}", parameters);

		//            if (_PATH_DDM.equals(pathArray[0])) {
		//                sendDDMRecordFile(request, response, pathArray);
		//            }
		//            else
		if (Validator.isNumber(pathArray[0])) {
			return getDocumentLibraryFileContents(pathArray, parameters);
		} else {
			// TODO support legacy image gallery ids
			//            if (isLegacyImageGalleryImageId(request, response)) {
			//                return null;
			//            }

			final Image image = getImage(true, parameters, pathArray);

			if (image != null) {
				return getImageContents(image, parameters);
			}
			//            else {
			//                sendDocumentLibrary(
			//                        request, response, user,
			//                        request.getServletPath() + StringPool.SLASH + path,
			//                        pathArray);
			//            }
		}
		return null;
	}

	/** Protected for unit test. */
	protected Map getParameters(final URI uri) {
		final String query = uri.getRawQuery();
		if (query == null || query.isEmpty()) {
			return Collections.emptyMap();
		}
		final Map parameters = new HashMap<>();
		final StringTokenizer st = new StringTokenizer(query, "&");
		while (st.hasMoreTokens()) {
			final String keyValuePair = st.nextToken();
			final int idx = keyValuePair.indexOf('=');
			if (idx == 0) {
				// do nothing
			} else if (idx == -1) {
				parameters.put(urlDecode(keyValuePair), "");
			} else if (idx == keyValuePair.length() - 1) {
				parameters.put(urlDecode(keyValuePair.substring(0, idx)), "");
			} else {
				parameters.put(urlDecode(keyValuePair.substring(0, idx)), urlDecode(keyValuePair.substring(idx + 1)));
			}
		}
		return parameters;
	}

	private String urlDecode(final String s) {
		try {
			return URLDecoder.decode(s, "UTF-8");
		} catch (final UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
	}

	/** Protected for unit test. */
	protected String[] getPathArray(final URI uri) {
		final StringTokenizer st = new StringTokenizer(uri.getPath(), StringPool.SLASH);
		final int count = st.countTokens();
		if (count < 2) {
			return null;
		}
		// skip first token
		st.nextToken();
		final String[] pathArray = new String[count - 1];
		for (int i = 0; i < count - 1; i++) {
			pathArray[i] = st.nextToken();
		}
		return pathArray;
	}

	/** See com.liferay.portal.webserver.WebServerServlet.sendFile(HttpServletRequest, HttpServletResponse, User, String[]) **/
	private DocumentLibraryFileContents getDocumentLibraryFileContents(final String[] pathArray, final Map parameters) throws Exception {
		// Retrieve file details

		final FileEntry fileEntry = getFileEntry(pathArray);

		if (fileEntry == null) {
			throw new NoSuchFileEntryException();
		}

		String version = parameters.get("version");
		if (Validator.isNull(version)) {
			if (Validator.isNotNull(fileEntry.getVersion())) {
				version = fileEntry.getVersion();
			}
		}
		final com.liferay.portal.kernel.repository.model.FileVersion fileVersion = fileEntry.getFileVersion(version);

		if (GetterUtil.getInteger(parameters.get("height")) > 0 || GetterUtil.getInteger(parameters.get("width")) > 0) {
			final Image image;
			try (final InputStream inputStream = fileVersion.getContentStream(true)) {
				image = LiferayAbstractionFactorySupplier.getInstance().getImageTool().getImage(inputStream);
			}
			return getImageContents(image, parameters);
		}

		String fileName = fileVersion.getTitle();
		final String extension = fileVersion.getExtension();
		if (Validator.isNotNull(extension) && !fileName.endsWith(StringPool.PERIOD + extension)) {
			fileName += StringPool.PERIOD + extension;
		}

		// Handle requested conversion

		boolean converted = false;

		final String targetExtension = GetterUtil.getString(parameters.get("targetExtension"));
		final int imageThumbnail = GetterUtil.getInteger(parameters.get("imageThumbnail"));
		final int documentThumbnail = GetterUtil.getInteger(parameters.get("documentThumbnail"));
		final int previewFileIndex = GetterUtil.getInteger(parameters.get("previewFileIndex"));
		//        boolean audioPreview = ParamUtil.getBoolean(request, "audioPreview");
		final boolean imagePreview = GetterUtil.getBoolean(parameters.get("imagePreview"));
		//        boolean videoPreview = ParamUtil.getBoolean(request, "videoPreview");
		//        int videoThumbnail = ParamUtil.getInteger(request, "videoThumbnail");

		InputStream inputStream = null;
		long contentLength = 0;

		if ((imageThumbnail > 0) && (imageThumbnail <= 3)) {
			fileName = FileUtil.stripExtension(fileName).concat(StringPool.PERIOD).concat(ImageProcessorUtil.getThumbnailType(fileVersion));
			final int thumbnailIndex = imageThumbnail - 1;
			inputStream = ImageProcessorUtil.getThumbnailAsStream(fileVersion, thumbnailIndex);
			contentLength = ImageProcessorUtil.getThumbnailFileSize(fileVersion, thumbnailIndex);
			converted = true;
		}
		else if ((documentThumbnail > 0) && (documentThumbnail <= 3)) {
			fileName = FileUtil.stripExtension(fileName).concat(StringPool.PERIOD).concat(PDFProcessor.THUMBNAIL_TYPE);
			final int thumbnailIndex = documentThumbnail - 1;
			inputStream = PDFProcessorUtil.getThumbnailAsStream(fileVersion, thumbnailIndex);
			contentLength = PDFProcessorUtil.getThumbnailFileSize(fileVersion, thumbnailIndex);
			converted = true;
		}
		else if (previewFileIndex > 0) {
			fileName = FileUtil.stripExtension(fileName).concat(StringPool.PERIOD).concat(PDFProcessor.PREVIEW_TYPE);
			inputStream = PDFProcessorUtil.getPreviewAsStream(fileVersion, previewFileIndex);
			contentLength = PDFProcessorUtil.getPreviewFileSize(fileVersion, previewFileIndex);
			converted = true;
		}
		//        else if (audioPreview || videoPreview) {
		//            String type = ParamUtil.getString(request, "type");
		//
		//            fileName = FileUtil.stripExtension(fileName).concat(
		//                    StringPool.PERIOD).concat(type);
		//
		//            if (audioPreview) {
		//                inputStream = AudioProcessorUtil.getPreviewAsStream(
		//                        fileVersion, type);
		//                contentLength = AudioProcessorUtil.getPreviewFileSize(
		//                        fileVersion, type);
		//            }
		//            else {
		//                inputStream = VideoProcessorUtil.getPreviewAsStream(
		//                        fileVersion, type);
		//                contentLength = VideoProcessorUtil.getPreviewFileSize(
		//                        fileVersion, type);
		//            }
		//
		//            converted = true;
		//        }
		else if (imagePreview) {
			final String type = ImageProcessorUtil.getPreviewType(fileVersion);
			fileName = FileUtil.stripExtension(fileName).concat(StringPool.PERIOD).concat(type);
			inputStream = ImageProcessorUtil.getPreviewAsStream(fileVersion);
			contentLength = ImageProcessorUtil.getPreviewFileSize(fileVersion);
			converted = true;
		}
		//        else if ((videoThumbnail > 0) && (videoThumbnail <= 3)) {
		//            fileName = FileUtil.stripExtension(fileName).concat(
		//                    StringPool.PERIOD).concat(VideoProcessor.THUMBNAIL_TYPE);
		//
		//            int thumbnailIndex = videoThumbnail - 1;
		//
		//            inputStream = VideoProcessorUtil.getThumbnailAsStream(
		//                    fileVersion, thumbnailIndex);
		//            contentLength = VideoProcessorUtil.getThumbnailFileSize(
		//                    fileVersion, thumbnailIndex);
		//
		//            converted = true;
		//        }
		else {
			inputStream = fileVersion.getContentStream(true);
			contentLength = fileVersion.getSize();
			if (Validator.isNotNull(targetExtension)) {
				final String tempFileId = DLUtil.getTempFileId(fileEntry.getFileEntryId(), version);
				final File convertedFile = DocumentConversionUtil.convert(tempFileId, inputStream, extension, targetExtension);
				if (convertedFile != null) {
					fileName = FileUtil.stripExtension(fileName).concat(StringPool.PERIOD).concat(targetExtension);
					inputStream = new FileInputStream(convertedFile);
					contentLength = convertedFile.length();
					converted = true;
				}
			}
		}

		// Determine proper content type

		String contentType = null;
		if (converted) {
			contentType = MimeTypesUtil.getContentType(fileName);
		} else {
			contentType = fileVersion.getMimeType();
		}

		//        if (_log.isDebugEnabled()) {
		//            _log.debug("Content type set to " + contentType);
		//        }
		//
		//        // Send file
		//
		//        if (isSupportsRangeHeader(contentType)) {
		//            sendFileWithRangeHeader(
		//                    request, response, fileName, inputStream, contentLength,
		//                    contentType);
		//        }
		//        else {
		//            ServletResponseUtil.sendFile(
		//                    request, response, fileName, inputStream, contentLength,
		//                    contentType);
		//        }

		return new DocumentLibraryFileContents(fileName, inputStream, contentLength, contentType);
	}

	private FileEntry getFileEntry(final String[] pathArray) throws Exception {
		if (pathArray.length == 1) {
			final long dlFileShortcutId = GetterUtil.getLong(pathArray[0]);

			final DLFileShortcut dlFileShortcut = DLAppServiceUtil.getFileShortcut(
					dlFileShortcutId);

			return DLAppServiceUtil.getFileEntry(
					dlFileShortcut.getToFileEntryId());
		}
		else if (pathArray.length == 2) {
			final long groupId = GetterUtil.getLong(pathArray[0]);

			return DLAppServiceUtil.getFileEntryByUuidAndGroupId(
					pathArray[1], groupId);
		}
		else if (pathArray.length == 3) {
			final long groupId = GetterUtil.getLong(pathArray[0]);
			final long folderId = GetterUtil.getLong(pathArray[1]);
			String fileName = HttpUtil.decodeURL(pathArray[2]);

			if (fileName.contains(StringPool.QUESTION)) {
				fileName = fileName.substring(
						0, fileName.indexOf(StringPool.QUESTION));
			}

			return DLAppServiceUtil.getFileEntry(groupId, folderId, fileName);
		}
		else {
			final long groupId = GetterUtil.getLong(pathArray[0]);

			final String uuid = pathArray[3];

			return DLAppServiceUtil.getFileEntryByUuidAndGroupId(uuid, groupId);
		}
	}

	/** See com.liferay.portal.webserver.WebServerServlet.writeImage(Image, HttpServletRequest, HttpServletResponse) */
	private DocumentLibraryFileContents getImageContents(final Image image, final Map parameters) {
		if (image == null) {
			return null;
		}

		String contentType = null;
		final String type = image.getType();
		if (!type.equals(ImageConstants.TYPE_NOT_AVAILABLE)) {
			contentType = MimeTypesUtil.getContentType("A." + type);
		}

		try {
			final byte[] bytes = getImageBytes(image, parameters);
			return new DocumentLibraryFileContents(null, new ByteArrayInputStream(bytes), bytes.length, contentType);
		} catch (final Exception e) {
			LOG.warn("Error getting image bytes", e);
			return null;
		}
	}

	/** com.liferay.portal.webserver.WebServerServlet.getImageBytes(HttpServletRequest, Image) */
	private byte[] getImageBytes(final Image image, final Map parameters) {
		try {
			if (!GetterUtil.getBoolean(PropsUtil.get(PropsKeys.IMAGE_AUTO_SCALE))) {
				return image.getTextObj();
			}

			ImageBag imageBag = null;

			if (image.getImageId() == 0) {
				imageBag = ImageToolUtil.read(image.getTextObj());

				final RenderedImage renderedImage = imageBag.getRenderedImage();

				image.setHeight(renderedImage.getHeight());
				image.setWidth(renderedImage.getWidth());
			}

			final int height = GetterUtil.getInteger(parameters.get("height"), image.getHeight());
			final int width = GetterUtil.getInteger(parameters.get("width"), image.getWidth());

			if ((height >= image.getHeight()) && (width >= image.getWidth())) {
				return image.getTextObj();
			}

			if (image.getImageId() != 0) {
				imageBag = ImageToolUtil.read(image.getTextObj());

				final RenderedImage renderedImage = ImageToolUtil.scale(
						imageBag.getRenderedImage(), height, width);

				return ImageToolUtil.getBytes(renderedImage, imageBag.getType());
			}
		}
		catch (final Exception e) {
			LOG.warn("Error scaling image {}", image.getImageId(), e);
		}

		return image.getTextObj();
	}

	private Image getImage(final boolean getDefault, final Map parameters, final String[] pathArray) throws LiferayException {

		Image image = null;

		final long imageId = getImageId(parameters);

		if (imageId > 0) {
			image = LiferayAbstractionFactorySupplier.getInstance().getImageTool().getImage(imageId);
			if (pathArray != null && pathArray.length > 0 &&
					("user_female_portrait".equals(pathArray[0]) ||
							"user_male_portrait".equals(pathArray[0]) ||
							"user_portrait".equals(pathArray[0]))) {
				image = getUserPortraitImageResized(image, imageId);
			}
		}
		else {
			final String uuid = GetterUtil.getString(parameters.get("uuid"));
			final long groupId = GetterUtil.getLong(parameters.get("groupId"));
			final boolean igSmallImage = GetterUtil.getBoolean(parameters.get("igSmallImage"));

			if (Validator.isNotNull(uuid) && (groupId > 0)) {
				try {
					final FileEntry fileEntry = DLAppServiceUtil.getFileEntryByUuidAndGroupId(uuid, groupId);
					image = convertFileEntry(igSmallImage, fileEntry);
				}
				catch (final Exception e) {
				}
			}
		}

		if (getDefault) {
			if (image == null) {
				LOG.warn("Get a default image for {}", imageId);
				image = getDefaultImage(pathArray, imageId);
			}
		}

		return image;
	}


	private long getImageId(final Map parameters) {
		// The image id may be passed in as image_id, img_id, or i_id
		long imageId = GetterUtil.getLong(parameters.get("image_id"));
		if (imageId <= 0) {
			imageId = GetterUtil.getLong(parameters.get("img_id"));
		}
		if (imageId <= 0) {
			imageId = GetterUtil.getLong(parameters.get("i_id"));
		}

		if (imageId <= 0) {
			final long companyId = GetterUtil.getLong(parameters.get("companyId"));
			final String screenName = GetterUtil.getString(parameters.get("screenName"));

			try {
				if ((companyId > 0) && Validator.isNotNull(screenName)) {
					final User user = UserLocalServiceUtil.getUserByScreenName(companyId, screenName);
					imageId = user.getPortraitId();
				}
			} catch (final Exception e) {
				LOG.warn("Error getting user portrait id", e);
			}
		}

		return imageId;
	}

	//    private DocumentLibraryFileContents getLegacyImageGalleryContents(HttpServletRequest request, HttpServletResponse response) {
	//
	//            try {
	//                long imageId = getImageId(request);
	//
	//                if (imageId == 0) {
	//                    return null;
	//                }
	//
	//                DLFileEntry dlFileEntry = DLFileEntryServiceUtil.fetchFileEntryByImageId(imageId);
	//
	//                if (dlFileEntry == null) {
	//                    return null;
	//                }
	//
	//                ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
	//                    WebKeys.THEME_DISPLAY);
	//
	//                String queryString = StringPool.BLANK;
	//
	//                if (imageId == dlFileEntry.getSmallImageId()) {
	//                    queryString = "&imageThumbnail=1";
	//                }
	//                else if (imageId == dlFileEntry.getCustom1ImageId()) {
	//                    queryString = "&imageThumbnail=2";
	//                }
	//                else if (imageId == dlFileEntry.getCustom2ImageId()) {
	//                    queryString = "&imageThumbnail=3";
	//                }
	//
	//                String url = DLUtil.getPreviewURL(
	//                    new LiferayFileEntry(dlFileEntry),
	//                    new LiferayFileVersion(dlFileEntry.getFileVersion()),
	//                    themeDisplay, queryString);
	//
	//                response.setHeader(HttpHeaders.LOCATION, url);
	//                response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
	//
	//                return true;
	//            }
	//            catch (Exception e) {
	//            }
	//
	//            return false;
	//        }

	private Image getUserPortraitImageResized(final Image image, final long imageId) throws LiferayException {
		if (image == null) {
			return null;
		}

		final int maxHeight = GetterUtil.getInteger(PropsUtil.get(PropsKeys.USERS_IMAGE_MAX_HEIGHT));
		final int maxWidth = GetterUtil.getInteger(PropsUtil.get(PropsKeys.USERS_IMAGE_MAX_WIDTH));
		if (((maxHeight > 0) &&
				(image.getHeight() > maxHeight)) ||
				((maxWidth > 0) &&
						(image.getWidth() > maxWidth))) {

			return LiferayAbstractionFactorySupplier.getInstance().getImageTool().updateUserPortrait(image, imageId);
		}

		return image;
	}

	private Image convertFileEntry(final boolean smallImage, final FileEntry fileEntry) throws Exception {
		final Image image = LiferayAbstractionFactorySupplier.getInstance().getImageTool().newImage();

		image.setModifiedDate(fileEntry.getModifiedDate());

		InputStream is = null;

		if (smallImage) {
			is = ImageProcessorUtil.getThumbnailAsStream(fileEntry.getFileVersion(), 0);
		} else {
			is = fileEntry.getContentStream();
		}

		final byte[] bytes = FileUtil.getBytes(is);
		image.setTextObj(bytes);
		image.setType(fileEntry.getExtension());
		return image;
	}

	private Image getDefaultImage(final String[] pathArray, final long imageId) {
		if (pathArray == null || pathArray.length == 0) {
			return null;
		}
		final String p = pathArray[0];

		if ("company_logo".equals(p) || "layout_set_logo".equals(p) || "logo".equals(p)) {
			return LiferayAbstractionFactorySupplier.getInstance().getImageTool().getDefaultCompanyLogo();
		}
		else if ("organization_logo".equals(p)) {
			return LiferayAbstractionFactorySupplier.getInstance().getImageTool().getDefaultOrganizationLogo();
		}
		else if ("user_female_portrait".equals(p)) {
			return LiferayAbstractionFactorySupplier.getInstance().getImageTool().getDefaultUserFemalePortrait();
		}
		else if ("user_male_portrait".equals(p)) {
			return LiferayAbstractionFactorySupplier.getInstance().getImageTool().getDefaultUserMalePortrait();
		}
		else if ("user_portrait".equals(p)) {
			return LiferayAbstractionFactorySupplier.getInstance().getImageTool().getDefaultUserMalePortrait();
		}
		else {
			return null;
		}
	}

	@Override
	public String getTempFileId(final FileVersion fileVersion) {
		final com.liferay.portal.kernel.repository.model.FileVersion liferayFileVersion = ((LiferayFileVersionWrapper)fileVersion).unwrap();
		return DLUtil.getTempFileId(liferayFileVersion.getFileEntryId(), liferayFileVersion.getVersion());
	}

	@Override
	public FileVersion wrapLiferayFileVersion(final Object liferayFileVersion) {
		return new LiferayFileVersionWrapper((com.liferay.portal.kernel.repository.model.FileVersion) liferayFileVersion);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy