DamContext.java
/*
* #%L
* wcm.io
* %%
* Copyright (C) 2020 wcm.io
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package io.wcm.handler.mediasource.dam.impl;
import java.util.Collections;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.adapter.Adaptable;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import com.day.cq.dam.api.Asset;
import com.day.cq.dam.scene7.api.constants.Scene7Constants;
import io.wcm.handler.media.Dimension;
import io.wcm.handler.media.MediaArgs;
import io.wcm.handler.media.impl.ImageQualityPercentage;
import io.wcm.handler.media.spi.MediaHandlerConfig;
import io.wcm.handler.mediasource.dam.impl.dynamicmedia.DynamicMediaSupportService;
import io.wcm.handler.mediasource.dam.impl.dynamicmedia.ImageProfile;
import io.wcm.handler.mediasource.dam.impl.dynamicmedia.NamedDimension;
import io.wcm.handler.mediasource.dam.impl.weboptimized.WebOptimizedImageDeliveryParams;
import io.wcm.handler.mediasource.dam.impl.weboptimized.WebOptimizedImageDeliveryService;
/**
* Context objects require in DAM support implementation.
*/
public final class DamContext implements Adaptable {
private final Asset asset;
private final MediaArgs mediaArgs;
private final MediaHandlerConfig mediaHandlerConfig;
private final DynamicMediaSupportService dynamicMediaSupportService;
private final WebOptimizedImageDeliveryService webOptimizedImageDeliveryService;
private final Adaptable adaptable;
private String dynamicMediaObject;
private String dynamicMediaServerUrl;
private Dimension dynamicMediaImageSizeLimit;
private ImageProfile imageProfile;
private static final ImageProfile NO_IMAGE_PROFILE = new ImageProfile() {
@Override
public @NotNull List<NamedDimension> getSmartCropDefinitions() {
return Collections.emptyList();
}
};
/**
* @param asset DAM asset
* @param mediaArgs Media Args from media request
* @param mediaHandlerConfig Media handler config
* @param dynamicMediaSupportService Dynamic media support service
* @param webOptimizedImageDeliveryService Web optimized image delivery service
* @param adaptable Adaptable from current context
*/
public DamContext(@NotNull Asset asset, @NotNull MediaArgs mediaArgs, @NotNull MediaHandlerConfig mediaHandlerConfig,
@NotNull DynamicMediaSupportService dynamicMediaSupportService,
@NotNull WebOptimizedImageDeliveryService webOptimizedImageDeliveryService,
@NotNull Adaptable adaptable) {
this.asset = asset;
this.mediaArgs = mediaArgs;
this.mediaHandlerConfig = mediaHandlerConfig;
this.dynamicMediaSupportService = dynamicMediaSupportService;
this.webOptimizedImageDeliveryService = webOptimizedImageDeliveryService;
this.adaptable = adaptable;
}
/**
* @return DAM asset
*/
public Asset getAsset() {
return asset;
}
/**
* @return Media Args from media request
*/
public MediaArgs getMediaArgs() {
return mediaArgs;
}
/**
* @return Media handler config
*/
public MediaHandlerConfig getMediaHandlerConfig() {
return this.mediaHandlerConfig;
}
/**
* @return Whether dynamic media is enabled on this AEM instance
*/
public boolean isDynamicMediaEnabled() {
// check that DM is not disabled globally
return dynamicMediaSupportService.isDynamicMediaEnabled()
// check that DM capability is enabled for the given asset
&& dynamicMediaSupportService.isDynamicMediaCapabilityEnabled(isDynamicMediaAsset())
// ensure DM is not disabled within MediaArgs for this media request
&& !mediaArgs.isDynamicMediaDisabled();
}
/**
* @return Whether a transparent fallback to Media Handler-based rendering of renditions is allowed
* if the appropriate Dynamic Media metadata is not preset for an asset.
*/
public boolean isDynamicMediaAemFallbackDisabled() {
return dynamicMediaSupportService.isAemFallbackDisabled();
}
/**
* @return Dynamic media object identifier (value of dam:scene7File property).
*/
public @Nullable String getDynamicMediaObject() {
if (dynamicMediaObject == null) {
dynamicMediaObject = asset.getMetadataValueFromJcr(Scene7Constants.PN_S7_FILE);
}
return dynamicMediaObject;
}
/**
* @return true if the DAM asset from this context has dynamic media metadata applied.
*/
public boolean isDynamicMediaAsset() {
return StringUtils.isNotBlank(getDynamicMediaObject());
}
/**
* @return Get scene7 host for publish environment. Empty string if author preview mode is active.
*/
public @Nullable String getDynamicMediaServerUrl() {
if (dynamicMediaServerUrl == null) {
dynamicMediaServerUrl = dynamicMediaSupportService.getDynamicMediaServerUrl(asset, mediaArgs.getUrlMode(), adaptable);
}
return dynamicMediaServerUrl;
}
/**
* @return Whether to validate that the renditions defined via smart cropping fulfill the requested image width/height
* to avoid upscaling or white borders.
*/
public boolean isDynamicMediaValidateSmartCropRenditionSizes() {
return dynamicMediaSupportService.isValidateSmartCropRenditionSizes();
}
/**
* @return Whether to control image quality for lossy output formats for each media request via 'qlt' URL parameter
* (instead of relying on default setting within Dynamic Media).
*/
public boolean isDynamicMediaSetImageQuality() {
return dynamicMediaSupportService.isSetImageQuality();
}
/**
* @return Dynamic media reply image size limit
*/
public @NotNull Dimension getDynamicMediaImageSizeLimit() {
if (dynamicMediaImageSizeLimit == null) {
dynamicMediaImageSizeLimit = dynamicMediaSupportService.getImageSizeLimit();
}
return dynamicMediaImageSizeLimit;
}
/**
* Get image profile for current DAM asset.
* @return Image profile or null if none associated/found
*/
public @Nullable ImageProfile getImageProfile() {
if (imageProfile == null) {
imageProfile = dynamicMediaSupportService.getImageProfileForAsset(asset);
if (imageProfile == null) {
imageProfile = NO_IMAGE_PROFILE;
}
}
if (imageProfile == NO_IMAGE_PROFILE) {
return null;
}
else {
return imageProfile;
}
}
/**
* @return Whether web-optimized image delivery is enabled on this AEM instance
*/
public boolean isWebOptimizedImageDeliveryEnabled() {
return webOptimizedImageDeliveryService.isEnabled();
}
/**
* Get web-optimized image delivery URL for a rendition of an asset.
* @param params Parameters
* @return Delivery URL or null if not supported or not enabled
*/
public @Nullable String getWebOptimizedImageDeliveryUrl(@NotNull WebOptimizedImageDeliveryParams params) {
// set image quality.
params.quality(ImageQualityPercentage.getAsInteger(this.mediaArgs, this.mediaHandlerConfig));
return webOptimizedImageDeliveryService.getDeliveryUrl(asset, params);
}
/**
* @return Resource resolver from current context
*/
public @NotNull ResourceResolver getResourceResolver() {
if (adaptable instanceof Resource) {
return ((Resource)adaptable).getResourceResolver();
}
else if (adaptable instanceof SlingHttpServletRequest) {
return ((SlingHttpServletRequest)adaptable).getResourceResolver();
}
else {
throw new IllegalStateException("Adaptable is neither Resoucre nor SlingHttpServletRequest");
}
}
@Override
public <AdapterType> @Nullable AdapterType adaptTo(@NotNull Class<AdapterType> type) {
return adaptable.adaptTo(type);
}
}