InlineUriTemplate.java

  1. /*
  2.  * #%L
  3.  * wcm.io
  4.  * %%
  5.  * Copyright (C) 2021 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.inline;

  21. import static io.wcm.handler.media.MediaNameConstants.URI_TEMPLATE_PLACEHOLDER_HEIGHT;
  22. import static io.wcm.handler.media.MediaNameConstants.URI_TEMPLATE_PLACEHOLDER_WIDTH;

  23. import org.apache.commons.lang3.StringUtils;
  24. import org.apache.sling.api.adapter.Adaptable;
  25. import org.apache.sling.api.resource.Resource;
  26. import org.jetbrains.annotations.NotNull;
  27. import org.jetbrains.annotations.Nullable;

  28. import io.wcm.handler.media.CropDimension;
  29. import io.wcm.handler.media.Dimension;
  30. import io.wcm.handler.media.MediaArgs;
  31. import io.wcm.handler.media.UriTemplate;
  32. import io.wcm.handler.media.UriTemplateType;
  33. import io.wcm.handler.media.impl.ImageFileServlet;
  34. import io.wcm.handler.media.impl.ImageFileServletSelector;
  35. import io.wcm.handler.media.impl.JcrBinary;
  36. import io.wcm.handler.media.impl.MediaFileServletConstants;
  37. import io.wcm.handler.url.UrlHandler;
  38. import io.wcm.sling.commons.adapter.AdaptTo;

  39. final class InlineUriTemplate implements UriTemplate {

  40.   private final String uriTemplate;
  41.   private final UriTemplateType type;
  42.   private final Dimension dimension;

  43.   @SuppressWarnings("java:S107") // allow more than 7 params
  44.   InlineUriTemplate(@NotNull UriTemplateType type, @NotNull Dimension dimension,
  45.       @NotNull Resource resource, @NotNull String fileName,
  46.       @Nullable CropDimension cropDimension, @Nullable Integer rotation,
  47.       @NotNull MediaArgs mediaArgs, @NotNull Adaptable adaptable) {
  48.     this.uriTemplate = buildUriTemplate(type, resource, fileName, cropDimension, rotation, mediaArgs, adaptable);
  49.     this.type = type;
  50.     this.dimension = dimension;
  51.   }

  52.   @SuppressWarnings("java:S1075") // not a file path
  53.   private static String buildUriTemplate(@NotNull UriTemplateType type, @NotNull Resource resource,
  54.       @NotNull String fileName, @Nullable CropDimension cropDimension, @Nullable Integer rotation,
  55.       @NotNull MediaArgs mediaArgs, @NotNull Adaptable adaptable) {
  56.     String resourcePath = resource.getPath();

  57.     // if parent resource is a nt:file resource, use this one as path for scaled image
  58.     Resource parentResource = resource.getParent();
  59.     if (parentResource != null && JcrBinary.isNtFile(parentResource)) {
  60.       resourcePath = parentResource.getPath();
  61.     }

  62.     // URL to render scaled image via {@link InlineRenditionServlet}
  63.     final long DUMMY_WIDTH = 999991;
  64.     final long DUMMY_HEIGHT = 999992;
  65.     String path = resourcePath
  66.         + "." + ImageFileServletSelector.build(DUMMY_WIDTH, DUMMY_HEIGHT, cropDimension, rotation,
  67.             mediaArgs.getImageQualityPercentage(), false)
  68.         + "." + MediaFileServletConstants.EXTENSION
  69.         // replace extension based on the format supported by ImageFileServlet for rendering for this rendition
  70.         + "/" + ImageFileServlet.getImageFileName(fileName, mediaArgs.getEnforceOutputFileExtension());

  71.     // build externalized URL
  72.     UrlHandler urlHandler = AdaptTo.notNull(adaptable, UrlHandler.class);
  73.     String url = urlHandler.get(path).urlMode(mediaArgs.getUrlMode()).buildExternalResourceUrl(resource);

  74.     switch (type) {
  75.       case CROP_CENTER:
  76.         url = StringUtils.replace(url, Long.toString(DUMMY_WIDTH), URI_TEMPLATE_PLACEHOLDER_WIDTH);
  77.         url = StringUtils.replace(url, Long.toString(DUMMY_HEIGHT), URI_TEMPLATE_PLACEHOLDER_HEIGHT);
  78.         break;
  79.       case SCALE_WIDTH:
  80.         url = StringUtils.replace(url, Long.toString(DUMMY_WIDTH), URI_TEMPLATE_PLACEHOLDER_WIDTH);
  81.         url = StringUtils.replace(url, Long.toString(DUMMY_HEIGHT), "0");
  82.         break;
  83.       case SCALE_HEIGHT:
  84.         url = StringUtils.replace(url, Long.toString(DUMMY_WIDTH), "0");
  85.         url = StringUtils.replace(url, Long.toString(DUMMY_HEIGHT), URI_TEMPLATE_PLACEHOLDER_HEIGHT);
  86.         break;
  87.       default:
  88.         throw new IllegalArgumentException("Unsupported type: " + type);
  89.     }
  90.     return url;
  91.   }

  92.   @Override
  93.   public @NotNull UriTemplateType getType() {
  94.     return type;
  95.   }

  96.   @Override
  97.   public @NotNull String getUriTemplate() {
  98.     return uriTemplate;
  99.   }

  100.   @Override
  101.   public long getMaxWidth() {
  102.     return dimension.getWidth();
  103.   }

  104.   @Override
  105.   public long getMaxHeight() {
  106.     return dimension.getHeight();
  107.   }

  108.   @Override
  109.   public String toString() {
  110.     return uriTemplate;
  111.   }

  112. }