PhotoItemDIDLAdapter.java

  1. /*
  2.  * *********************************************************************************************************************
  3.  *
  4.  * blueMarine II: Semantic Media Centre
  5.  * http://tidalwave.it/projects/bluemarine2
  6.  *
  7.  * Copyright (C) 2015 - 2021 by Tidalwave s.a.s. (http://tidalwave.it)
  8.  *
  9.  * *********************************************************************************************************************
  10.  *
  11.  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
  12.  * the License. You may obtain a copy of the License at
  13.  *
  14.  *     http://www.apache.org/licenses/LICENSE-2.0
  15.  *
  16.  * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
  17.  * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the
  18.  * specific language governing permissions and limitations under the License.
  19.  *
  20.  * *********************************************************************************************************************
  21.  *
  22.  * git clone https://bitbucket.org/tidalwave/bluemarine2-src
  23.  * git clone https://github.com/tidalwave-it/bluemarine2-src
  24.  *
  25.  * *********************************************************************************************************************
  26.  */
  27. package it.tidalwave.bluemarine2.service.stoppingdown.impl;

  28. import javax.annotation.Nonnull;
  29. import javax.annotation.concurrent.Immutable;
  30. import java.util.List;
  31. import java.nio.file.Path;
  32. import it.tidalwave.bluemarine2.model.spi.PathAwareEntity;
  33. import org.fourthline.cling.support.model.DIDLObject;
  34. import org.fourthline.cling.support.model.Protocol;
  35. import org.fourthline.cling.support.model.ProtocolInfo;
  36. import org.fourthline.cling.support.model.Res;
  37. import org.fourthline.cling.support.model.dlna.DLNAProtocolInfo;
  38. import org.fourthline.cling.support.model.item.Photo;
  39. import it.tidalwave.dci.annotation.DciRole;
  40. import it.tidalwave.bluemarine2.upnp.mediaserver.impl.didl.DIDLAdapter;
  41. import lombok.RequiredArgsConstructor;
  42. import static java.util.Collections.reverseOrder;

  43. /***********************************************************************************************************************
  44.  *
  45.  * A role that converts a {@link PhotoItem} into DIDL content.
  46.  *
  47.  * @stereotype  Role
  48.  *
  49.  * @author  Fabrizio Giudici
  50.  *
  51.  **********************************************************************************************************************/
  52.  // FIXME: this introduces a dependency on UPnP. It's needed because it contains stuff related to StoppingDown (URLs).
  53.  // FIXME: move PhotoItem to Model, this class to UPnP and try to make the URLs contained in metadata of PhotoItem.
  54. @RequiredArgsConstructor
  55. @Immutable @DciRole(datumType = PhotoItem.class)
  56. public class PhotoItemDIDLAdapter implements DIDLAdapter
  57.   {
  58.     private static final String MEDIA_URL_TEMPLATE =
  59.             PhotoCollectionProviderSupport.URL_STOPPINGDOWN + "/media/stillimages/%s/%d/image.jpg";

  60.     private static final List<Integer> SIZES = List.of(200, 400, 800, 1280, 1920, 2560);

  61.     @Nonnull
  62.     private final PhotoItem datum;

  63.     private final String creator = "Fabrizio Giudici";

  64.     /*******************************************************************************************************************
  65.      *
  66.      * {@inheritDoc}
  67.      *
  68.      ******************************************************************************************************************/
  69.     @Override @Nonnull
  70.     public DIDLObject toObject()
  71.       {
  72.         final ProtocolInfo protocolInfo = new DLNAProtocolInfo(Protocol.HTTP_GET, "*", "image/jpeg", "*");
  73.         final Res[] resources = SIZES.stream()
  74.                                      .sorted(reverseOrder())
  75.                                      .map(size -> createResource(protocolInfo, size))
  76.                                      .toArray(Res[]::new);
  77.         final Path parentPath = datum.getParent().map(PathAwareEntity::getPath).orElseThrow(RuntimeException::new);
  78.         final String parentId = parentPath.toString();
  79.         final String photoId = parentPath.resolve(datum.getId()).toString();
  80.         final String title = datum.getId();
  81.         final Photo item = new Photo(photoId, parentId, title, creator, parentId, resources);
  82.         item.setDescription(datum.getTitle());
  83.         item.setDate(dateFor(datum.getId()));
  84.         return item;
  85.       }

  86.     /*******************************************************************************************************************
  87.      *
  88.      ******************************************************************************************************************/
  89.     @Nonnull
  90.     private Res createResource (@Nonnull final ProtocolInfo protocolInfo, final int size)
  91.       {
  92.         final Res resource = new Res(protocolInfo, null, computeUrl(size));
  93.         resource.setResolution(size, size);
  94.         return resource;
  95.       }

  96.     /*******************************************************************************************************************
  97.      *
  98.      ******************************************************************************************************************/
  99.     @Nonnull
  100.     private String computeUrl (final int size)
  101.       {
  102.         return String.format(MEDIA_URL_TEMPLATE, datum.getId(), size);
  103.       }

  104.     /*******************************************************************************************************************
  105.      *
  106.      ******************************************************************************************************************/
  107.     @Nonnull
  108.     private static String dateFor (final String id)
  109.       {
  110.         return String.format("%s-%s-%s", id.substring(0, 4), id.substring(4, 6), id.substring(6, 8));
  111.       }
  112.   }