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

com.liferay.adaptive.media.image.internal.media.query.MediaQueryProviderImpl Maven / Gradle / Ivy

/**
 * SPDX-FileCopyrightText: (c) 2000 Liferay, Inc. https://liferay.com
 * SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06
 */

package com.liferay.adaptive.media.image.internal.media.query;

import com.liferay.adaptive.media.AdaptiveMedia;
import com.liferay.adaptive.media.image.configuration.AMImageConfigurationEntry;
import com.liferay.adaptive.media.image.configuration.AMImageConfigurationHelper;
import com.liferay.adaptive.media.image.finder.AMImageFinder;
import com.liferay.adaptive.media.image.internal.configuration.AMImageAttributeMapping;
import com.liferay.adaptive.media.image.internal.processor.AMImage;
import com.liferay.adaptive.media.image.media.query.Condition;
import com.liferay.adaptive.media.image.media.query.MediaQuery;
import com.liferay.adaptive.media.image.media.query.MediaQueryProvider;
import com.liferay.adaptive.media.image.processor.AMImageAttribute;
import com.liferay.adaptive.media.image.processor.AMImageProcessor;
import com.liferay.adaptive.media.image.url.AMImageURLFactory;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.repository.model.FileEntry;
import com.liferay.portal.kernel.util.StringBundler;

import java.net.URI;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

/**
 * @author Alejandro Tardín
 */
@Component
public class MediaQueryProviderImpl implements MediaQueryProvider {

	@Override
	public List getMediaQueries(FileEntry fileEntry)
		throws PortalException {

		Collection> adaptiveMedias =
			_getAdaptiveMedias(fileEntry);

		List mediaQueries = new ArrayList<>();
		AdaptiveMedia previousAdaptiveMedia = null;

		for (AdaptiveMedia adaptiveMedia : adaptiveMedias) {
			Optional> hdAdaptiveMediaOptional =
				_getHDAdaptiveMedia(adaptiveMedia, adaptiveMedias);

			mediaQueries.add(
				_getMediaQuery(
					adaptiveMedia, previousAdaptiveMedia,
					hdAdaptiveMediaOptional));

			previousAdaptiveMedia = adaptiveMedia;
		}

		return mediaQueries;
	}

	@Reference(unbind = "-")
	protected void setAMImageConfigurationHelper(
		AMImageConfigurationHelper amImageConfigurationHelper) {

		_amImageConfigurationHelper = amImageConfigurationHelper;
	}

	@Reference(unbind = "-")
	protected void setAMImageFinder(AMImageFinder amImageFinder) {
		_amImageFinder = amImageFinder;
	}

	@Reference(unbind = "-")
	protected void setAMImageURLFactory(AMImageURLFactory amImageURLFactory) {
		_amImageURLFactory = amImageURLFactory;
	}

	private Optional> _findAdaptiveMedia(
		FileEntry fileEntry,
		AMImageConfigurationEntry amImageConfigurationEntry) {

		try {
			Stream> adaptiveMediaStream =
				_amImageFinder.getAdaptiveMediaStream(
					amImageQueryBuilder -> amImageQueryBuilder.forFileEntry(
						fileEntry
					).forConfiguration(
						amImageConfigurationEntry.getUUID()
					).done());

			return adaptiveMediaStream.findFirst();
		}
		catch (PortalException pe) {
			if (_log.isWarnEnabled()) {
				_log.warn(pe, pe);
			}

			return Optional.empty();
		}
	}

	private AdaptiveMedia
		_getAdaptiveMediaFromConfigurationEntry(
			FileEntry fileEntry,
			AMImageConfigurationEntry amImageConfigurationEntry) {

		Optional> adaptiveMediaOptional =
			_findAdaptiveMedia(fileEntry, amImageConfigurationEntry);

		if (adaptiveMediaOptional.isPresent()) {
			return adaptiveMediaOptional.get();
		}

		Optional widthOptional = _getWidth(amImageConfigurationEntry);
		Optional heightOptional = _getHeight(
			amImageConfigurationEntry);

		Map properties = new HashMap<>();

		properties.put(
			AMImageAttribute.AM_IMAGE_ATTRIBUTE_WIDTH.getName(),
			String.valueOf(widthOptional.orElse(0)));

		properties.put(
			AMImageAttribute.AM_IMAGE_ATTRIBUTE_HEIGHT.getName(),
			String.valueOf(heightOptional.orElse(0)));

		return new AMImage(
			() -> null, AMImageAttributeMapping.fromProperties(properties),
			_getFileEntryURL(fileEntry, amImageConfigurationEntry));
	}

	private Collection> _getAdaptiveMedias(
			FileEntry fileEntry)
		throws PortalException {

		Collection amImageConfigurationEntries =
			_amImageConfigurationHelper.getAMImageConfigurationEntries(
				fileEntry.getCompanyId());

		List> adaptiveMedias =
			new ArrayList<>();

		for (AMImageConfigurationEntry amImageConfigurationEntry :
				amImageConfigurationEntries) {

			AdaptiveMedia adaptiveMedia =
				_getAdaptiveMediaFromConfigurationEntry(
					fileEntry, amImageConfigurationEntry);

			if (_getWidth(adaptiveMedia) > 0) {
				adaptiveMedias.add(adaptiveMedia);
			}
		}

		Collections.sort(adaptiveMedias, _comparator);

		return adaptiveMedias;
	}

	private List _getConditions(
		AdaptiveMedia adaptiveMedia,
		AdaptiveMedia previousAdaptiveMedia) {

		List conditions = new ArrayList<>();

		conditions.add(
			new Condition("max-width", _getWidth(adaptiveMedia) + "px"));

		if (previousAdaptiveMedia != null) {
			conditions.add(
				new Condition(
					"min-width", _getWidth(previousAdaptiveMedia) + "px"));
		}

		return conditions;
	}

	private URI _getFileEntryURL(
		FileEntry fileEntry,
		AMImageConfigurationEntry amImageConfigurationEntry) {

		try {
			return _amImageURLFactory.createFileEntryURL(
				fileEntry.getFileVersion(), amImageConfigurationEntry);
		}
		catch (PortalException pe) {
			throw new RuntimeException(pe);
		}
	}

	private Optional> _getHDAdaptiveMedia(
		AdaptiveMedia originalAdaptiveMedia,
		Collection> adaptiveMedias) {

		for (AdaptiveMedia adaptiveMedia : adaptiveMedias) {
			int originalWidth = _getWidth(originalAdaptiveMedia) * 2;
			int originalHeight = _getHeight(originalAdaptiveMedia) * 2;

			IntStream widthIntStream = IntStream.range(
				originalWidth - 1, originalWidth + 2);

			boolean widthMatch = widthIntStream.anyMatch(
				value -> value == _getWidth(adaptiveMedia));

			IntStream heightIntStream = IntStream.range(
				originalHeight - 1, originalHeight + 2);

			boolean heightMatch = heightIntStream.anyMatch(
				value -> value == _getHeight(adaptiveMedia));

			if (widthMatch && heightMatch) {
				return Optional.of(adaptiveMedia);
			}
		}

		return Optional.empty();
	}

	private Integer _getHeight(AdaptiveMedia adaptiveMedia) {
		Optional optional = adaptiveMedia.getValueOptional(
			AMImageAttribute.AM_IMAGE_ATTRIBUTE_HEIGHT);

		return optional.orElse(0);
	}

	private Optional _getHeight(
		AMImageConfigurationEntry originalAMImageConfigurationEntry) {

		return _getPropertiesValue(
			originalAMImageConfigurationEntry, "max-height");
	}

	private MediaQuery _getMediaQuery(
			AdaptiveMedia adaptiveMedia,
			AdaptiveMedia previousAdaptiveMedia,
			Optional> hdAdaptiveMediaOptional)
		throws PortalException {

		StringBundler sb = new StringBundler(4);

		List conditions = _getConditions(
			adaptiveMedia, previousAdaptiveMedia);

		sb.append(adaptiveMedia.getURI());

		hdAdaptiveMediaOptional.ifPresent(
			hdAdaptiveMedia -> {
				sb.append(", ");
				sb.append(hdAdaptiveMedia.getURI());
				sb.append(" 2x");
			});

		return new MediaQuery(conditions, sb.toString());
	}

	private Optional _getPropertiesValue(
		AMImageConfigurationEntry amImageConfigurationEntry, String name) {

		try {
			Map properties =
				amImageConfigurationEntry.getProperties();

			Integer height = Integer.valueOf(properties.get(name));

			return Optional.of(height);
		}
		catch (NumberFormatException nfe) {
			return Optional.empty();
		}
	}

	private Integer _getWidth(AdaptiveMedia adaptiveMedia) {
		Optional attributeValue = adaptiveMedia.getValueOptional(
			AMImageAttribute.AM_IMAGE_ATTRIBUTE_WIDTH);

		return attributeValue.orElse(0);
	}

	private Optional _getWidth(
		AMImageConfigurationEntry amImageConfigurationEntry) {

		return _getPropertiesValue(amImageConfigurationEntry, "max-width");
	}

	private static final Log _log = LogFactoryUtil.getLog(
		MediaQueryProviderImpl.class);

	private AMImageConfigurationHelper _amImageConfigurationHelper;
	private AMImageFinder _amImageFinder;
	private AMImageURLFactory _amImageURLFactory;
	private final Comparator> _comparator =
		Comparator.comparingInt(this::_getWidth);

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy