DefaultDevicePublisher.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.upnp.mediaserver.impl.device;

  28. import javax.annotation.Nonnull;
  29. import javax.annotation.PostConstruct;
  30. import javax.inject.Inject;
  31. import java.util.Arrays;
  32. import java.util.Collections;
  33. import java.util.List;
  34. import java.net.InetAddress;
  35. import java.net.URI;
  36. import java.net.UnknownHostException;
  37. import java.util.Optional;
  38. import org.fourthline.cling.UpnpService;
  39. import org.fourthline.cling.binding.annotations.AnnotationLocalServiceBinder;
  40. import org.fourthline.cling.model.DefaultServiceManager;
  41. import org.fourthline.cling.model.ValidationException;
  42. import org.fourthline.cling.model.meta.DeviceDetails;
  43. import org.fourthline.cling.model.meta.DeviceIdentity;
  44. import org.fourthline.cling.model.meta.Icon;
  45. import org.fourthline.cling.model.meta.LocalDevice;
  46. import org.fourthline.cling.model.meta.LocalService;
  47. import org.fourthline.cling.model.meta.ManufacturerDetails;
  48. import org.fourthline.cling.model.meta.ModelDetails;
  49. import org.fourthline.cling.model.types.DLNACaps;
  50. import org.fourthline.cling.model.types.DLNADoc;
  51. import org.fourthline.cling.model.types.UDADeviceType;
  52. import org.fourthline.cling.model.types.UDN;
  53. import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
  54. import lombok.Getter;
  55. import lombok.RequiredArgsConstructor;
  56. import lombok.Setter;
  57. import lombok.extern.slf4j.Slf4j;

  58. /***********************************************************************************************************************
  59.  *
  60.  * @author  Fabrizio Giudici
  61.  *
  62.  **********************************************************************************************************************/
  63. @RequiredArgsConstructor @Slf4j
  64. public class DefaultDevicePublisher<T> implements DevicePublisher<T>
  65.   {
  66.     @Inject
  67.     private UpnpService upnpService;

  68.     @Inject
  69.     private AutowireCapableBeanFactory beanFactory;

  70.     private final Class<?> serviceClass;

  71.     private LocalService service;

  72.     private DefaultServiceManager<T>  serviceManager;

  73.     private final AnnotationLocalServiceBinder serviceBinder = new AnnotationLocalServiceBinder();

  74.     @Getter @Setter
  75.     private boolean autoPublish = true;

  76.     @Getter @Setter
  77.     private UDN udn;

  78.     @Getter @Setter
  79.     private String friendlyName = "bm II";

  80.     @Getter @Setter
  81.     private boolean useHostNameInFriendlyName = true;

  82.     @Getter @Setter
  83.     private String serialNumber = "n.a.";

  84.     @Getter @Setter
  85.     private String version = "n.a.";

  86.     @Getter @Setter
  87.     private UDADeviceType udaDeviceType = new UDADeviceType("MediaServer", 1);

  88.     @Getter @Setter
  89.     private int maxAge = 1800;

  90.     @Getter @Setter
  91.     private String modelName = "blueMarine II media server";

  92.     @Getter @Setter
  93.     private String presentationUri;

  94.     @Getter @Setter
  95.     private ManufacturerDetails manufacturerDetails = new ManufacturerDetails("Tidalwave s.a.s.", "http://tidalwave.it");

  96.     @Getter @Setter
  97.     private ModelDetails modelDetails = new ModelDetails(modelName,
  98.                                                          modelName,
  99.                                                          version,
  100.                                                          "http://bluemarine.tidalwave.it");

  101.     @Getter @Setter
  102.     private List<DLNADoc> dlnaDocs = Arrays.asList
  103.       (
  104.         new DLNADoc("DMS", DLNADoc.Version.V1_5),
  105.         new DLNADoc("M-DMS", DLNADoc.Version.V1_5)
  106.       );

  107.     @Getter @Setter
  108.     private List<String> dlnaCaps = Arrays.asList
  109.       (
  110.         "av-upload", "image-upload", "audio-upload"
  111.       );

  112.     @Getter @Setter
  113.     private List<Icon> icons = Collections.emptyList();

  114.     private LocalDevice device;

  115.     private ValidationException exception;

  116.     /*******************************************************************************************************************
  117.      *
  118.      * {@inheritDoc}
  119.      *
  120.      ******************************************************************************************************************/
  121.     @Override @Nonnull
  122.     public LocalDevice getDevice()
  123.       throws ValidationException
  124.       {
  125.         if (exception != null)
  126.           {
  127.             throw exception;
  128.           }

  129.         assert device != null;

  130.         return device;
  131.       }

  132.     /*******************************************************************************************************************
  133.      *
  134.      * {@inheritDoc}
  135.      *
  136.      ******************************************************************************************************************/
  137.     @Override
  138.     public void publishDevice()
  139.       throws ValidationException
  140.       {
  141.         try
  142.           {
  143.             udn = UDN.uniqueSystemIdentifier("1");
  144.             service = serviceBinder.read(serviceClass);
  145.             serviceManager = new AutowireServiceManager<>(beanFactory, service, serviceClass);
  146.             service.setManager(serviceManager);
  147.             log.info("publishDevice() - {}", service);
  148.             final DeviceDetails deviceDetails = new DeviceDetails(computeFriendyName(),
  149.                                                                   manufacturerDetails,
  150.                                                                   modelDetails,
  151.                                                                   serialNumber,
  152.                                                                   null, // UPC
  153.                                                                   Optional.ofNullable(presentationUri).map(URI::create).orElse(null),
  154.                                                                   dlnaDocs.toArray(new DLNADoc[0]),
  155.                                                                   new DLNACaps(dlnaCaps.toArray(new String[0])));
  156.             device = new LocalDevice(new DeviceIdentity(udn, maxAge),
  157.                                      udaDeviceType,
  158.                                      deviceDetails,
  159.                                      icons.toArray(new Icon[0]),
  160.                                      service);
  161.             upnpService.getRegistry().addDevice(device);
  162.           }
  163.         catch (ValidationException e)
  164.           {
  165.             this.exception = e;
  166.             throw e;
  167.           }
  168.       }

  169.     /*******************************************************************************************************************
  170.      *
  171.      *
  172.      ******************************************************************************************************************/
  173.     @PostConstruct
  174.     private void initialize()
  175.       {
  176.         if (autoPublish)
  177.           {
  178.             try
  179.               {
  180.                 publishDevice();
  181.               }
  182.             catch (RuntimeException | ValidationException e)
  183.               {
  184.                 log.error("Could not publish device", e);
  185.               }
  186.           }
  187.       }

  188.     /*******************************************************************************************************************
  189.      *
  190.      *
  191.      ******************************************************************************************************************/
  192.     @Nonnull
  193.     private String computeFriendyName()
  194.       {
  195.         final StringBuilder buffer = new StringBuilder(friendlyName);

  196.         if (useHostNameInFriendlyName)
  197.           {
  198.             try
  199.               {
  200.                 buffer.append(" (").append(InetAddress.getLocalHost().getCanonicalHostName()).append(")");
  201.               }
  202.             catch (UnknownHostException e)
  203.               {
  204.                 log.warn("Cannot get host name", e);
  205.               }
  206.           }

  207.         return buffer.toString();
  208.       }
  209.   }