View Javadoc
1   /*
2    * #%L
3    * wcm.io
4    * %%
5    * Copyright (C) 2020 wcm.io
6    * %%
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   *
11   *      http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   * #L%
19   */
20  package io.wcm.handler.mediasource.dam.impl;
21  
22  import java.util.Collections;
23  import java.util.List;
24  
25  import org.apache.commons.lang3.StringUtils;
26  import org.apache.sling.api.SlingHttpServletRequest;
27  import org.apache.sling.api.adapter.Adaptable;
28  import org.apache.sling.api.resource.Resource;
29  import org.apache.sling.api.resource.ResourceResolver;
30  import org.jetbrains.annotations.NotNull;
31  import org.jetbrains.annotations.Nullable;
32  
33  import com.day.cq.dam.api.Asset;
34  import com.day.cq.dam.scene7.api.constants.Scene7Constants;
35  
36  import io.wcm.handler.media.Dimension;
37  import io.wcm.handler.media.MediaArgs;
38  import io.wcm.handler.media.spi.MediaHandlerConfig;
39  import io.wcm.handler.mediasource.dam.impl.dynamicmedia.DynamicMediaSupportService;
40  import io.wcm.handler.mediasource.dam.impl.dynamicmedia.ImageProfile;
41  import io.wcm.handler.mediasource.dam.impl.dynamicmedia.NamedDimension;
42  import io.wcm.handler.mediasource.dam.impl.weboptimized.WebOptimizedImageDeliveryParams;
43  import io.wcm.handler.mediasource.dam.impl.weboptimized.WebOptimizedImageDeliveryService;
44  import io.wcm.handler.mediasource.ngdm.impl.ImageQualityPercentage;
45  
46  /**
47   * Context objects require in DAM support implementation.
48   */
49  public final class DamContext implements Adaptable {
50  
51    private final Asset asset;
52    private final MediaArgs mediaArgs;
53    private final MediaHandlerConfig mediaHandlerConfig;
54    private final DynamicMediaSupportService dynamicMediaSupportService;
55    private final WebOptimizedImageDeliveryService webOptimizedImageDeliveryService;
56    private final Adaptable adaptable;
57  
58    private String dynamicMediaObject;
59    private String dynamicMediaServerUrl;
60    private Dimension dynamicMediaImageSizeLimit;
61    private ImageProfile imageProfile;
62  
63    private static final ImageProfile NO_IMAGE_PROFILE = new ImageProfile() {
64      @Override
65      public @NotNull List<NamedDimension> getSmartCropDefinitions() {
66        return Collections.emptyList();
67      }
68    };
69  
70    /**
71     * @param asset DAM asset
72     * @param mediaArgs Media Args from media request
73     * @param mediaHandlerConfig Media handler config
74     * @param dynamicMediaSupportService Dynamic media support service
75     * @param webOptimizedImageDeliveryService Web optimized image delivery service
76     * @param adaptable Adaptable from current context
77     */
78    public DamContext(@NotNull Asset asset, @NotNull MediaArgs mediaArgs, @NotNull MediaHandlerConfig mediaHandlerConfig,
79        @NotNull DynamicMediaSupportService dynamicMediaSupportService,
80        @NotNull WebOptimizedImageDeliveryService webOptimizedImageDeliveryService,
81        @NotNull Adaptable adaptable) {
82      this.asset = asset;
83      this.mediaArgs = mediaArgs;
84      this.mediaHandlerConfig = mediaHandlerConfig;
85      this.dynamicMediaSupportService = dynamicMediaSupportService;
86      this.webOptimizedImageDeliveryService = webOptimizedImageDeliveryService;
87      this.adaptable = adaptable;
88    }
89  
90    /**
91     * @return DAM asset
92     */
93    public Asset getAsset() {
94      return asset;
95    }
96  
97    /**
98     * @return Media Args from media request
99     */
100   public MediaArgs getMediaArgs() {
101     return mediaArgs;
102   }
103 
104   /**
105    * @return Media handler config
106    */
107   public MediaHandlerConfig getMediaHandlerConfig() {
108     return this.mediaHandlerConfig;
109   }
110 
111   /**
112    * @return Whether dynamic media is enabled on this AEM instance
113    */
114   public boolean isDynamicMediaEnabled() {
115     // check that DM is not disabled globally
116     return dynamicMediaSupportService.isDynamicMediaEnabled()
117         // check that DM capability is enabled for the given asset
118         && dynamicMediaSupportService.isDynamicMediaCapabilityEnabled(isDynamicMediaAsset())
119         // ensure DM is not disabled within MediaArgs for this media request
120         && !mediaArgs.isDynamicMediaDisabled();
121   }
122 
123   /**
124    * @return Whether a transparent fallback to Media Handler-based rendering of renditions is allowed
125    *         if the appropriate Dynamic Media metadata is not preset for an asset.
126    */
127   public boolean isDynamicMediaAemFallbackDisabled() {
128     return dynamicMediaSupportService.isAemFallbackDisabled();
129   }
130 
131   /**
132    * @return Dynamic media object identifier (value of dam:scene7File property).
133    */
134   public @Nullable String getDynamicMediaObject() {
135     if (dynamicMediaObject == null) {
136       dynamicMediaObject = asset.getMetadataValueFromJcr(Scene7Constants.PN_S7_FILE);
137     }
138     return dynamicMediaObject;
139   }
140 
141   /**
142    * @return true if the DAM asset from this context has dynamic media metadata applied.
143    */
144   public boolean isDynamicMediaAsset() {
145     return StringUtils.isNotBlank(getDynamicMediaObject());
146   }
147 
148   /**
149    * @return Get scene7 host for publish environment. Empty string if author preview mode is active.
150    */
151   public @Nullable String getDynamicMediaServerUrl() {
152     if (dynamicMediaServerUrl == null) {
153       dynamicMediaServerUrl = dynamicMediaSupportService.getDynamicMediaServerUrl(asset, mediaArgs.getUrlMode(), adaptable);
154     }
155     return dynamicMediaServerUrl;
156   }
157 
158   /**
159    * @return Whether to validate that the renditions defined via smart cropping fulfill the requested image width/height
160    *         to avoid upscaling or white borders.
161    */
162   public boolean isDynamicMediaValidateSmartCropRenditionSizes() {
163     return dynamicMediaSupportService.isValidateSmartCropRenditionSizes();
164   }
165 
166   /**
167    * @return Dynamic media reply image size limit
168    */
169   public @NotNull Dimension getDynamicMediaImageSizeLimit() {
170     if (dynamicMediaImageSizeLimit == null) {
171       dynamicMediaImageSizeLimit = dynamicMediaSupportService.getImageSizeLimit();
172     }
173     return dynamicMediaImageSizeLimit;
174   }
175 
176   /**
177    * Get image profile for current DAM asset.
178    * @return Image profile or null if none associated/found
179    */
180   public @Nullable ImageProfile getImageProfile() {
181     if (imageProfile == null) {
182       imageProfile = dynamicMediaSupportService.getImageProfileForAsset(asset);
183       if (imageProfile == null) {
184         imageProfile = NO_IMAGE_PROFILE;
185       }
186     }
187     if (imageProfile == NO_IMAGE_PROFILE) {
188       return null;
189     }
190     else {
191       return imageProfile;
192     }
193   }
194 
195   /**
196    * @return Whether web-optimized image delivery is enabled on this AEM instance
197    */
198   public boolean isWebOptimizedImageDeliveryEnabled() {
199     return webOptimizedImageDeliveryService.isEnabled();
200   }
201 
202   /**
203    * Get web-optimized image delivery URL for a rendition of an asset.
204    * @param params Parameters
205    * @return Delivery URL or null if not supported or not enabled
206    */
207   public @Nullable String getWebOptimizedImageDeliveryUrl(@NotNull WebOptimizedImageDeliveryParams params) {
208 
209     // set image quality.
210     params.quality(ImageQualityPercentage.getAsInteger(this.mediaArgs, this.mediaHandlerConfig));
211 
212     return webOptimizedImageDeliveryService.getDeliveryUrl(asset, params);
213   }
214 
215   /**
216    * @return Resource resolver from current context
217    */
218   public @NotNull ResourceResolver getResourceResolver() {
219     if (adaptable instanceof Resource) {
220       return ((Resource)adaptable).getResourceResolver();
221     }
222     else if (adaptable instanceof SlingHttpServletRequest) {
223       return ((SlingHttpServletRequest)adaptable).getResourceResolver();
224     }
225     else {
226       throw new IllegalStateException("Adaptable is neither Resoucre nor SlingHttpServletRequest");
227     }
228   }
229 
230   @Override
231   public <AdapterType> @Nullable AdapterType adaptTo(@NotNull Class<AdapterType> type) {
232     return adaptable.adaptTo(type);
233   }
234 
235 }