DefaultUrlMode.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.url.impl.modes;

  21. import java.util.Set;

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

  28. import com.day.cq.wcm.api.Page;

  29. import io.wcm.handler.url.UrlModes;
  30. import io.wcm.handler.url.integrator.IntegratorHandler;
  31. import io.wcm.handler.url.spi.UrlHandlerConfig;
  32. import io.wcm.sling.commons.adapter.AdaptTo;
  33. import io.wcm.wcm.commons.util.Path;

  34. /**
  35.  * Default mode: Does generate a full externalized URL only if both siteUrl and siteUrlSecure parameter
  36.  * are set in context-specific configuration. If not set, only URLs without hostname are generated.
  37.  * If the target is an internal content page, siteUrl or siteUrlSecure is chosen automatically depending on the secure
  38.  * state of the page.
  39.  */
  40. public final class DefaultUrlMode extends AbstractUrlMode {

  41.   @Override
  42.   public @NotNull String getId() {
  43.     return "DEFAULT";
  44.   }

  45.   @Override
  46.   public String getLinkUrlPrefix(@NotNull Adaptable adaptable, @NotNull Set<String> runModes,
  47.       @Nullable Page currentPage, @Nullable Page targetPage) {
  48.     // default to full url for content URLs
  49.     return UrlModes.FULL_URL.getLinkUrlPrefix(adaptable, runModes, currentPage, targetPage);
  50.   }

  51.   @Override
  52.   public String getResourceUrlPrefix(@NotNull Adaptable adaptable, @NotNull Set<String> runModes,
  53.       @Nullable Page currentPage, @Nullable Resource targetResource) {
  54.     // in integrator template mode or if resource is from another site default to full URL mode, otherwise to no-hostname mode
  55.     IntegratorHandler integratorHandler = AdaptTo.notNull(adaptable, IntegratorHandler.class);
  56.     if (integratorHandler.isIntegratorTemplateMode()
  57.         || linksToOtherDomain(adaptable, currentPage, targetResource)) {
  58.       return UrlModes.FULL_URL.getResourceUrlPrefix(adaptable, runModes, currentPage, targetResource);
  59.     }
  60.     return UrlModes.NO_HOSTNAME.getResourceUrlPrefix(adaptable, runModes, currentPage, targetResource);
  61.   }

  62.   /**
  63.    * Checks if the target resource is located outsite the current site, and if for this other
  64.    * resource context a valid url configuration with a specific hostname exists.
  65.    * @param adaptable Adaptable
  66.    * @param currentPage Current page (may be null)
  67.    * @param targetResource Target resource (may be null)
  68.    * @return true if the target resources is located in another site/context with separate url configuration
  69.    */
  70.   private boolean linksToOtherDomain(Adaptable adaptable, Page currentPage, Resource targetResource) {
  71.     if (currentPage == null || targetResource == null) {
  72.       return false;
  73.     }

  74.     UrlHandlerConfig urlHandlerConfig = AdaptTo.notNull(adaptable, UrlHandlerConfig.class);
  75.     Resource currentResource = AdaptTo.notNull(currentPage, Resource.class);
  76.     ResourceResolver resourceResolver = currentResource.getResourceResolver();
  77.     String currentSiteRoot = getRootPath(currentPage.getPath(), urlHandlerConfig.getSiteRootLevel(currentResource), resourceResolver);
  78.     String pathSiteRoot = getRootPath(targetResource.getPath(), urlHandlerConfig.getSiteRootLevel(targetResource), resourceResolver);
  79.     boolean notInCurrentSite = !StringUtils.equals(currentSiteRoot, pathSiteRoot);

  80.     if (notInCurrentSite) {
  81.       UrlConfig targetUrlConfig = new UrlConfig(targetResource);
  82.       return targetUrlConfig.isValid();
  83.     }
  84.     else {
  85.       return false;
  86.     }
  87.   }

  88.   /**
  89.    * Gets site root level path of a site.
  90.    * @param path Path of page within the site
  91.    * @param rootLevel Level of root page
  92.    * @param resourceResolver Resource resolver
  93.    * @return Site root path for the site. The path is not checked for validness.
  94.    */
  95.   private String getRootPath(String path, int rootLevel, ResourceResolver resourceResolver) {
  96.     String rootPath = Path.getAbsoluteParent(path, rootLevel, resourceResolver);

  97.     // strip off everything after first "." - root path may be passed with selectors/extension which is not relevant
  98.     if (StringUtils.contains(rootPath, ".")) {
  99.       rootPath = StringUtils.substringBefore(rootPath, ".");
  100.     }

  101.     return rootPath;
  102.   }

  103. }