<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>BluetteGalleryAdapter.java</title><link rel="stylesheet" href="../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">NorthernWind :: Frontend :: Components :: HTML Template</a> > <a href="index.source.html" class="el_package">it.tidalwave.northernwind.frontend.ui.component.gallery.htmltemplate.bluette</a> > <span class="el_source">BluetteGalleryAdapter.java</span></div><h1>BluetteGalleryAdapter.java</h1><pre class="source lang-java linenums">/*
* #%L
* *********************************************************************************************************************
*
* NorthernWind - lightweight CMS
* http://northernwind.tidalwave.it - git clone https://bitbucket.org/tidalwave/northernwind-src.git
* %%
* Copyright (C) 2011 - 2023 Tidalwave s.a.s. (http://tidalwave.it)
* %%
* *********************************************************************************************************************
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* *********************************************************************************************************************
*
*
* *********************************************************************************************************************
* #L%
*/
package it.tidalwave.northernwind.frontend.ui.component.gallery.htmltemplate.bluette;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import java.util.List;
import java.util.Optional;
import it.tidalwave.util.Id;
import it.tidalwave.util.Key;
import it.tidalwave.northernwind.core.model.ModelFactory;
import it.tidalwave.northernwind.core.model.ResourcePath;
import it.tidalwave.northernwind.core.model.ResourceProperties;
import it.tidalwave.northernwind.core.model.Site;
import it.tidalwave.northernwind.core.model.SiteNode;
import it.tidalwave.northernwind.core.model.Template;
import it.tidalwave.northernwind.core.model.Template.Aggregate;
import it.tidalwave.northernwind.frontend.ui.RenderContext;
import it.tidalwave.northernwind.frontend.ui.component.htmltemplate.TextHolder;
import it.tidalwave.northernwind.frontend.ui.component.gallery.GalleryView;
import it.tidalwave.northernwind.frontend.ui.component.gallery.GalleryViewController.GalleryItem;
import it.tidalwave.northernwind.frontend.ui.component.gallery.spi.GalleryAdapterSupport;
import lombok.extern.slf4j.Slf4j;
import static it.tidalwave.northernwind.core.model.Template.Aggregates.toAggregates;
/***********************************************************************************************************************
*
* @author Fabrizio Giudici
*
**********************************************************************************************************************/
<span class="nc" id="L55">@Slf4j</span>
public class BluetteGalleryAdapter extends GalleryAdapterSupport
{
<span class="nc" id="L58"> private static final Key<String> P_COPYRIGHT = Key.of("copyright", String.class);</span>
<span class="nc" id="L60"> private static final Key<ResourcePath> P_BLUETTE_TEMPLATE_PATH = Key.of("bluettePath", ResourcePath.class);</span>
/** The path to the template for fallback rendering of a single gallery page, when JavaScript is not available. */
<span class="nc" id="L63"> private static final Key<ResourcePath> P_BLUETTE_FALLBACK_TEMPLATE_PATH = Key.of("bluetteFallbackPath", ResourcePath.class);</span>
/** The path to the template for fallback rendering of the light box, when JavaScript is not available. */
<span class="nc" id="L66"> private static final Key<ResourcePath> P_BLUETTE_LIGHTBOX_FALLBACK_TEMPLATE_PATH = Key.of("bluetteLightboxFallbackPath", ResourcePath.class);</span>
/** The path to the template for the script that redirects a page to the dynamic counterpart (with #!). */
<span class="nc" id="L69"> private static final Key<ResourcePath> P_BLUETTE_REDIRECT_SCRIPT_TEMPLATE_PATH = Key.of("bluetteRedirectScriptPath", ResourcePath.class);</span>
/** The path to the template for the image catalog. */
<span class="nc" id="L72"> private static final Key<ResourcePath> P_BLUETTE_CATALOG_TEMPLATE_PATH = Key.of("bluetteCatalogPath", ResourcePath.class);</span>
<span class="nc" id="L74"> private static final Key<ResourcePath> P_BLUETTE_VARIABLES_TEMPLATE_PATH = Key.of("bluetteVariablesPath", ResourcePath.class);</span>
<span class="nc" id="L76"> private static final Key<String> P_CATALOG_URL = Key.of("bluetteCatalogUrl", String.class);</span>
@Nonnull
private final Site site;
@Nonnull
private final Template defaultTemplate;
@Nonnull
private final Template fallbackTemplate;
@Nonnull
private final Template lightboxFallbackTemplate;
@Nonnull
private final Template redirectScriptTemplate;
@Nonnull
private final Template catalogTemplate;
@Nonnull
private final Template variablesTemplate;
@Nonnull
private final ResourceProperties bluetteConfiguration;
@Nonnull
private final ResourcePath baseUrl;
@Nonnull
private final String copyright;
<span class="nc" id="L108"> private final int fallbackImageSize = 1280; // FIXME: parametrise size</span>
<span class="nc" id="L110"> private final int fallbackThumbnailSize = 100; // FIXME: parametrise size</span>
parametrise size
<span class="nc" id="L112"> private final ResourcePath lightboxSegmentUri = ResourcePath.of("lightbox");</span>
@Nonnull
private final String homeUrl;
<span class="nc" id="L117"> private String rendered = "";</span>
private boolean catalog;
/*******************************************************************************************************************
*
*
*
******************************************************************************************************************/
public BluetteGalleryAdapter (@Nonnull final SiteNode siteNode,
@Nonnull final GalleryView view,
@Nonnull final ModelFactory modelFactory)
{
<span class="nc" id="L130"> super(siteNode, view, modelFactory);</span>
<span class="nc" id="L131"> this.site = siteNode.getSite();</span>
<span class="nc" id="L132"> bluetteConfiguration = siteNode.getPropertyGroup(new Id("bluetteConfiguration"));</span>
<span class="nc" id="L133"> baseUrl = siteNode.getRelativeUri().prependedWith(site.getContextPath());</span>
<span class="nc" id="L134"> homeUrl = site.createLink(ResourcePath.of("/blog")); // FIXME</span>
<span class="nc" id="L135"> copyright = bluetteConfiguration.getProperty(P_COPYRIGHT).orElse("");</span>
<span class="nc" id="L137"> defaultTemplate = loadTemplate(P_BLUETTE_TEMPLATE_PATH, "Default.st");</span>
<span class="nc" id="L138"> fallbackTemplate = loadTemplate(P_BLUETTE_FALLBACK_TEMPLATE_PATH, "Fallback.st");</span>
<span class="nc" id="L139"> lightboxFallbackTemplate = loadTemplate(P_BLUETTE_LIGHTBOX_FALLBACK_TEMPLATE_PATH, "LightBoxFallback.st");</span>
<span class="nc" id="L140"> redirectScriptTemplate = loadTemplate(P_BLUETTE_REDIRECT_SCRIPT_TEMPLATE_PATH, "RedirectScript.st");</span>
<span class="nc" id="L141"> catalogTemplate = loadTemplate(P_BLUETTE_CATALOG_TEMPLATE_PATH, "Catalog.st");</span>
<span class="nc" id="L142"> variablesTemplate = loadTemplate(P_BLUETTE_VARIABLES_TEMPLATE_PATH, "Variables.st");</span>
<span class="nc" id="L143"> }</span>
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override @Nonnull
public String getInlinedScript()
{
<span class="nc" id="L153"> final var link = site.createLink(siteNode.getRelativeUri().appendedWith("images.xml"));</span>
<span class="nc" id="L154"> final var properties = bluetteConfiguration.withProperty(P_CATALOG_URL, "'" + link + "'");</span>
// FIXME: since key doesn't have dynamic type, we can't properly escape strings.
<span class="nc" id="L156"> final var variables = properties.getKeys().stream()</span>
<span class="nc bnc" id="L157" title="All 4 branches missed."> .filter(k -> k.getName().startsWith("bluette") || "logging".equals(k.getName()))</span>
<span class="nc" id="L158"> .flatMap(k -> toAggregate(properties, k).stream())</span>
<span class="nc" id="L159"> .collect(toAggregates("entries"));</span>
<span class="nc" id="L161"> return variablesTemplate.render(variables) + "\n" + redirectScriptTemplate.render();</span>
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override
public void prepareCatalog (@Nonnull final List<? extends GalleryItem> items)
{
<span class="nc" id="L172"> final var entries = items.stream().map(this::toAggregate).collect(toAggregates("entries"));</span>
<span class="nc" id="L173"> rendered = catalogTemplate.render(entries);</span>
<span class="nc" id="L174"> catalog = true;</span>
<span class="nc" id="L175"> }</span>
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
// TODO: Could we manage #! params here and select the proper item?
@Override
public void prepareGallery (@Nonnull final GalleryItem item, @Nonnull final List<? extends GalleryItem> items)
{
<span class="nc" id="L186"> prepare(item, items, defaultTemplate);</span>
<span class="nc" id="L187"> rendered = defaultTemplate.render();</span>
<span class="nc" id="L188"> }</span>
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override
public void prepareFallbackGallery (@Nonnull final GalleryItem item, @Nonnull final List<? extends GalleryItem> items)
{
<span class="nc" id="L198"> prepare(item, items, fallbackTemplate);</span>
<span class="nc" id="L199"> rendered = fallbackTemplate.render();</span>
<span class="nc" id="L200"> }</span>
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override
public void prepareFallbackLightbox (@Nonnull final List<? extends GalleryItem> items)
{
<span class="nc" id="L210"> final var entries = items.stream().map(this::toAggregate).collect(toAggregates("entries"));</span>
<span class="nc" id="L211"> final var redirectUrl = site.createLink(baseUrl.appendedWith("#!").appendedWith(lightboxSegmentUri)).replaceAll("/$", "");</span>
<span class="nc" id="L212"> redirectScriptTemplate.addAttribute("redirectUrl", redirectUrl);</span>
<span class="nc" id="L213"> lightboxFallbackTemplate.addAttribute("copyright", copyright);</span>
<span class="nc" id="L214"> rendered = lightboxFallbackTemplate.render(entries);</span>
<span class="nc" id="L215"> }</span>
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override
public void render (@Nonnull final RenderContext context)
{
<span class="nc" id="L225"> final var textHolder = (TextHolder)view;</span>
<span class="nc bnc" id="L227" title="All 2 branches missed."> if (!catalog)</span>
{
<span class="nc" id="L229"> textHolder.addAttribute("content", rendered);</span>
}
else
{
<span class="nc" id="L233"> textHolder.setTemplate("$content$\n");</span>
<span class="nc" id="L234"> textHolder.setContent(rendered);</span>
<span class="nc" id="L235"> textHolder.setMimeType("text/xml");</span>
}
<span class="nc" id="L237"> }</span>
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
private void prepare (// final @Nonnull RenderContext context,
@Nonnull final GalleryItem item,
@Nonnull final List<? extends GalleryItem> items,
@Nonnull final Template template)
{
<span class="nc" id="L248"> final var count = items.size();</span>
<span class="nc" id="L249"> final var index = items.indexOf(item);</span>
<span class="nc" id="L250"> final var prevIndex = (index - 1 + count) % count;</span>
<span class="nc" id="L251"> final var nextIndex = (index + 1) % count;</span>
<span class="nc" id="L253"> final var imageId = item.getId().stringValue();</span>
<span class="nc" id="L254"> final var imageUrl = createImageLink(imageId, fallbackImageSize);</span>
<span class="nc" id="L256"> final var redirectUrl = site.createLink(baseUrl.appendedWith("#!").appendedWith(imageId)).replaceAll("/$", "");</span>
<span class="nc" id="L257"> final var previousUrl = site.createLink(baseUrl.appendedWith(items.get(prevIndex).getId().stringValue()));</span>
<span class="nc" id="L258"> final var nextUrl = site.createLink(baseUrl.appendedWith(items.get(nextIndex).getId().stringValue()));</span>
<span class="nc" id="L259"> final var lightboxUrl = site.createLink(baseUrl.appendedWith(lightboxSegmentUri));</span>
<span class="nc" id="L261"> template.addAttribute("caption", item.getDescription())</span>
<span class="nc" id="L262"> .addAttribute("previous", previousUrl)</span>
<span class="nc" id="L263"> .addAttribute("next", nextUrl)</span>
<span class="nc" id="L264"> .addAttribute("lightbox", lightboxUrl)</span>
<span class="nc" id="L265"> .addAttribute("home", homeUrl)</span>
<span class="nc" id="L266"> .addAttribute("imageId", imageId)</span>
<span class="nc" id="L267"> .addAttribute("imageUrl", imageUrl)</span>
<span class="nc" id="L268"> .addAttribute("copyright", copyright);</span>
<span class="nc bnc" id="L270" title="All 2 branches missed."> if (template != defaultTemplate)</span>
{
<span class="nc" id="L272"> redirectScriptTemplate.addAttribute("redirectUrl", redirectUrl);</span>
// context.setDynamicNodeProperty(PD_IMAGE_ID, imageId);
// FIXME: these should be dynamic properties
// siteNodeProperties.getProperty().ifPresent(id -> view.addAttribute("imageId", id));
// siteNodeProperties.getProperty(PD_URL).ifPresent(id -> view.addAttribute("url", id));
<span class="nc" id="L278"> final var textHolder = (TextHolder)view;</span>
<span class="nc" id="L279"> textHolder.addAttribute("description", item.getDescription());</span>
<span class="nc" id="L280"> textHolder.addAttribute("imageId", imageId);</span>
<span class="nc" id="L281"> textHolder.addAttribute("imageUrl", imageUrl);</span>
}
<span class="nc" id="L283"> }</span>
/*******************************************************************************************************************
*
******************************************************************************************************************/
@Nonnull
private Aggregate toAggregate (@Nonnull final GalleryItem item)
{
<span class="nc" id="L291"> final var id = item.getId().stringValue();</span>
<span class="nc" id="L292"> final var link = site.createLink(baseUrl.appendedWith(id));</span>
<span class="nc" id="L293"> return Aggregate.of("id", id)</span>
<span class="nc" id="L294"> .with("link", link)</span>
<span class="nc" id="L295"> .with("url", createImageLink(id, fallbackThumbnailSize))</span>
<span class="nc" id="L296"> .with("title", item.getDescription().replaceAll("\n+", " "));</span>
}
/*******************************************************************************************************************
*
******************************************************************************************************************/
@Nonnull
private static Optional<Aggregate> toAggregate (@Nonnull final ResourceProperties properties,
@Nonnull final Key<?> key)
{
// A space in front of [ ] makes them interpreted as a string and not a list.
<span class="nc" id="L307"> return properties.getProperty(key).map(v -> Aggregate.of("name", key.stringValue()).with("value", v.toString().replace("[", " [")));</span>
}
/*******************************************************************************************************************
*
******************************************************************************************************************/
@Nonnull
private String createImageLink (@Nonnull final String id, @Nonnegative final int size)
{
<span class="nc" id="L316"> return site.createLink(ResourcePath.of(String.format("/media/stillimages/%d/%s.jpg", size, id)));</span>
}
}
</pre><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.9.202303310957</span></div></body></html>