MediaLinkType.java

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

  21. import java.util.HashMap;
  22. import java.util.Map;

  23. import org.apache.commons.lang3.StringUtils;
  24. import org.apache.sling.api.SlingHttpServletRequest;
  25. import org.apache.sling.api.resource.Resource;
  26. import org.apache.sling.api.resource.ResourceResolver;
  27. import org.apache.sling.api.resource.ValueMap;
  28. import org.apache.sling.models.annotations.Model;
  29. import org.apache.sling.models.annotations.injectorspecific.Self;
  30. import org.jetbrains.annotations.NotNull;
  31. import org.jetbrains.annotations.Nullable;
  32. import org.osgi.annotation.versioning.ProviderType;

  33. import io.wcm.handler.link.Link;
  34. import io.wcm.handler.link.LinkNameConstants;
  35. import io.wcm.handler.link.LinkRequest;
  36. import io.wcm.handler.link.SyntheticLinkResource;
  37. import io.wcm.handler.link.spi.LinkType;
  38. import io.wcm.handler.media.Media;
  39. import io.wcm.handler.media.MediaArgs;
  40. import io.wcm.handler.media.MediaHandler;

  41. /**
  42.  * Default implementation of {@link io.wcm.handler.link.spi.LinkType} for media links.
  43.  * Media links are links to media items from media sources
  44.  * that implement the {@link io.wcm.handler.media.spi.MediaSource} interface.
  45.  */
  46. @Model(adaptables = {
  47.     SlingHttpServletRequest.class, Resource.class
  48. })
  49. @ProviderType
  50. public final class MediaLinkType extends LinkType {

  51.   /**
  52.    * Default root folder für DAM
  53.    */
  54.   private static final String DEFAULT_DAM_ROOT = "/content/dam/";

  55.   /**
  56.    * Link type ID
  57.    */
  58.   public static final @NotNull String ID = "media";

  59.   @Self
  60.   private MediaHandler mediaHandler;

  61.   /**
  62.    * @return Link type ID (is stored as identifier in repository)
  63.    */
  64.   @Override
  65.   public @NotNull String getId() {
  66.     return ID;
  67.   }

  68.   @Override
  69.   public @NotNull String getLabel() {
  70.     return "Asset";
  71.   }

  72.   @Override
  73.   public String getPrimaryLinkRefProperty() {
  74.     return LinkNameConstants.PN_LINK_MEDIA_REF;
  75.   }

  76.   @Override
  77.   public @Nullable String getEditComponentResourceType() {
  78.     return "wcm-io/handler/link/components/granite/form/linktype/media";
  79.   }

  80.   @Override
  81.   public boolean hasRichTextPlugin() {
  82.     return true;
  83.   }

  84.   @Override
  85.   public boolean accepts(@NotNull String linkRef) {
  86.     // accept as media link if the ref is inside default media subtrees
  87.     return isDefaultMediaContentPath(linkRef);
  88.   }

  89.   @SuppressWarnings("null")
  90.   @Override
  91.   public @NotNull Link resolveLink(@NotNull Link link) {
  92.     LinkRequest linkRequest = link.getLinkRequest();
  93.     ValueMap props = linkRequest.getResourceProperties();

  94.     // get properties
  95.     String mediaRef = StringUtils.defaultString(props.get(LinkNameConstants.PN_LINK_MEDIA_REF, String.class),
  96.         link.getLinkRequest().getReference());
  97.     boolean isDownload = props.get(LinkNameConstants.PN_LINK_MEDIA_DOWNLOAD, false);

  98.     MediaArgs mediaArgs = new MediaArgs()
  99.         // only allow linking to "download" media formats
  100.         .download(true)
  101.         // content disposition header for download links
  102.         .contentDispositionAttachment(isDownload)
  103.         // disable web-optimized image delivery to get asset in original resolution
  104.         .webOptimizedImageDeliveryDisabled(true)
  105.         .urlMode(linkRequest.getLinkArgs().getUrlMode());

  106.     // resolve media library reference
  107.     Media media = mediaHandler.get(mediaRef, mediaArgs).build();

  108.     // set resovled media references information in link metadata
  109.     link.setUrl(media.getUrl());
  110.     link.setTargetAsset(media.getAsset());
  111.     link.setTargetRendition(media.getRendition());

  112.     // mark link as invalid if a reference was set that could not be resolved
  113.     if (link.getUrl() == null && StringUtils.isNotEmpty(mediaRef)) {
  114.       link.setLinkReferenceInvalid(true);
  115.     }

  116.     return link;
  117.   }

  118.   /**
  119.    * @param path Content path
  120.    * @return true if Path is located below DAM default root folders.
  121.    */
  122.   public static boolean isDefaultMediaContentPath(String path) {
  123.     return StringUtils.startsWith(path, DEFAULT_DAM_ROOT);
  124.   }

  125.   /**
  126.    * Get synthetic link resource for this link type.
  127.    * @param resourceResolver Resource resolver
  128.    * @param path Resource path. Can be a non-existing path, but the path should be located somewhere within the
  129.    *          applications content paths to make sure the handler configuration looked up via context-aware services
  130.    *          is the expected one.
  131.    * @param mediaRef Media asset reference
  132.    * @return Synthetic link resource
  133.    */
  134.   public static @NotNull Resource getSyntheticLinkResource(@NotNull ResourceResolver resourceResolver,
  135.       @NotNull String path, @NotNull String mediaRef) {
  136.     Map<String, Object> map = new HashMap<>();
  137.     map.put(LinkNameConstants.PN_LINK_TYPE, ID);
  138.     map.put(LinkNameConstants.PN_LINK_MEDIA_REF, mediaRef);
  139.     return new SyntheticLinkResource(resourceResolver, path, map);
  140.   }

  141.   @Override
  142.   public String toString() {
  143.     return ID;
  144.   }

  145. }