Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
8.2 kB
4
Indexable
Never
package ca.homedepot.core.components.internal.models.v1;

import ca.homedepot.core.components.models.Image;
import ca.homedepot.core.components.models.vo.HotSpotItem;
import ca.homedepot.core.components.models.vo.HotspotButtonStyle;
import ca.homedepot.core.components.models.vo.datalayer.analytics.BaseAnalyticsDataLayerItem;
import ca.homedepot.core.components.models.vo.datalayer.analytics.HotspotDataLayerItem;
import ca.homedepot.core.filters.DataLayerInterceptorFilter;
import ca.homedepot.core.util.Constants;
import com.day.cq.commons.Externalizer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableMap;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.OSGiService;
import org.apache.sling.models.annotations.injectorspecific.Self;
import org.apache.sling.models.annotations.injectorspecific.SlingObject;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;


/**
 * @author Sarav
 * Defines the {@code Image} Sling Model Implementation used for the
 * {@code /apps/homedepot/components/content/image} component.
 */
@Model(adaptables = SlingHttpServletRequest.class,
  adapters = Image.class,
  resourceType = ImageImpl.RESOURCE_TYPE, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class ImageImpl implements Image
{

  /*String literals*/
  static final String RESOURCE_TYPE = "homedepot/components/content/image";
  private static final DecimalFormat PERCENT_FORMAT = new DecimalFormat("0.00");
  private static final Logger LOGGER = LoggerFactory.getLogger(ImageImpl.class);
  public static final String RESPONSIVEGRID_BUTTON = "jcr:content/root/responsivegrid/button";
  public static final String LINK = "link";
  public static final String RESPONSIVEGRID_TEXT = "jcr:content/root/responsivegrid/text";
  public static final String H2_TAG = "h2";
  public static final String P_TAG = "p";
  public static final String TEXT = "text";
  public static final String CONTENT_EXPERIENCE_FRAGMENTS = "/content/experience-fragments/";

  /* Component dialog properties */
  @Self
  private SlingHttpServletRequest request;
  @ValueMapValue
  private String categoryQuery;
  @ValueMapValue
  private String link;
  @ValueMapValue
  private String imageMap;
  @ValueMapValue
  private String altText;

  @OSGiService
  private Externalizer externalizer;
  @SlingObject
  private ResourceResolver resourceResolver;

  private List<HotSpotItem> hotspots;
  private String hotspotString;
  private String updatedLinkWithQueryParam;
  private String publishDomain;

  public ImageImpl()
  {
    // Default constructor required for sling to load this model from page.
  }

  @PostConstruct
  protected void initModel()
  {
    updatedLinkWithQueryParam = StringUtils.isNotBlank(categoryQuery) ? String.format(Constants.LINK_WITH_QUERY, link, categoryQuery) :
      link;
    if (StringUtils.isNotBlank(imageMap))
    {
      processHotspots();
    }
    publishDomain = externalizer.publishLink(resourceResolver, StringUtils.EMPTY);
  }

  private void processHotspots()
  {
    hotspots = new ArrayList<>();
    Pattern pattern1 = Pattern.compile("^\\[circle\\((.*)\\)\"(.*)\"\\|\"(.*)\"\\|\"(.*)\"\\|\\((.*),(.*),(.*)\\)$");
    Arrays.asList(StringUtils.splitByWholeSeparator(imageMap, "]")).forEach(str ->
    {
      Matcher matcher = pattern1.matcher(str);
      if (matcher.matches())
      {
        String hotspotAltText = matcher.group(4);
        String leftPosition = getPercentage(matcher.group(5));
        String topPosition = getPercentage(matcher.group(6));

        HotSpotItem hotSpotItem = new HotSpotItem(matcher.group(2), getButtonPosition(topPosition, leftPosition),
          new HotspotButtonStyle(topPosition, leftPosition), hotspotAltText);
        String xfPath = matcher.group(2);
        Resource xfResource = resourceResolver.resolve(xfPath);
        boolean isXF = matcher.group(2).contains(CONTENT_EXPERIENCE_FRAGMENTS);
        if (isXF)
        {
          setPropertiesFromXf(hotSpotItem, xfResource);
        }
        hotspots.add(hotSpotItem);
      }
    });
    try
    {
      hotspotString = new ObjectMapper().writeValueAsString(hotspots);
    } catch (IOException e)
    {
      LOGGER.error(e.getMessage(), e);
    }
    updateAnalyticsData();
  }

  private void setPropertiesFromXf(HotSpotItem hotSpotItem, Resource xfResource)
  {
    Resource xfTextResource = xfResource.getChild(RESPONSIVEGRID_TEXT);
    if (Objects.nonNull(xfTextResource))
    {
      String text = xfTextResource.getValueMap().get(TEXT, StringUtils.EMPTY);

      Document document = Jsoup.parse(text);

      Elements h2Elements = document.getElementsByTag(H2_TAG);
      String hotspotTitle = h2Elements.isEmpty() ? StringUtils.EMPTY : h2Elements.get(0).text();

      Elements paragraphElements = document.getElementsByTag(P_TAG);
      String hotspotSubTitle = paragraphElements.isEmpty() ? StringUtils.EMPTY : paragraphElements.get(0).text();

      hotSpotItem.setHspotsTitle(hotspotTitle);
      hotSpotItem.setHspotsSubTitle(hotspotSubTitle);
    }

    Resource xfButtonResource = xfResource.getChild(RESPONSIVEGRID_BUTTON);
    if (Objects.nonNull(xfButtonResource))
    {
      String destinationUrl = xfButtonResource.getValueMap().get(LINK, StringUtils.EMPTY);
      hotSpotItem.setHspotsDestinationLink(resourceResolver.map(destinationUrl));
    }
  }

  private String getButtonPosition(String topPercentage, String leftPercentage)
  {
    return (NumberUtils.toFloat(topPercentage) > 50f ? "top: auto; bottom: 2rem;" : "top: 2rem; bottom: auto;") +
      (NumberUtils.toFloat(leftPercentage) > 50f ? "left: auto; right: 2rem;" : "left: 2rem; right: auto;");
  }

  private String getPercentage(String coordinate)
  {
    return PERCENT_FORMAT.format(NumberUtils.toFloat(coordinate) * 100) + "%";
  }

  private void updateAnalyticsData()
  {
    Optional.ofNullable((BaseAnalyticsDataLayerItem) request.getAttribute(DataLayerInterceptorFilter.ANALYTICS_DATA_ATTRIBUTE)).ifPresent(dataLayer ->
    {
      HotspotDataLayerItem hotspotDataLayerItem = new HotspotDataLayerItem();
      hotspotDataLayerItem.put("displayGroupName", altText);
      hotspotDataLayerItem.put("productListing",
        hotspots.stream().filter(hotspot -> !StringUtils.contains(hotspot.getProductId(), "/content/experience-fragments"))
          .map(hotspot -> ImmutableMap.of("code", hotspot.getProductId()))
          .collect(Collectors.toList()));

      List<HotSpotItem> hotSpotItems = hotspots.stream()
        .filter(hotspot -> !StringUtils.contains(hotspot.getProductId(), "/content/experience-fragments"))
        .collect(Collectors.toList());
      hotSpotItems.forEach(hotSpotItem -> {hotSpotItem.setButtonStyle(null);
      hotSpotItem.setPanelPosition(null);
      hotSpotItem.setProductId(null);
      }
      );
      hotspotDataLayerItem.put("hspotsTooltip", hotSpotItems);

      dataLayer.getHotspots().add(hotspotDataLayerItem);
      request.setAttribute(DataLayerInterceptorFilter.ANALYTICS_DATA_ATTRIBUTE, dataLayer);
    });
  }

  @Override
  public String getUpdatedLinkWithQueryParam()
  {
    return updatedLinkWithQueryParam;
  }

  @Override
  public String getHotspotString()
  {
    return hotspotString;
  }

  @Override
  public String getPublishDomain()
  {
    return publishDomain;
  }
}