ModelBuilder.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.util;

  28. import javax.annotation.Nonnull;
  29. import javax.annotation.concurrent.ThreadSafe;
  30. import java.util.List;
  31. import java.util.Optional;
  32. import java.util.stream.Stream;
  33. import org.eclipse.rdf4j.model.IRI;
  34. import org.eclipse.rdf4j.model.Model;
  35. import org.eclipse.rdf4j.model.Resource;
  36. import org.eclipse.rdf4j.model.Statement;
  37. import org.eclipse.rdf4j.model.Value;
  38. import org.eclipse.rdf4j.model.impl.TreeModel;

  39. /***********************************************************************************************************************
  40.  *
  41.  * Unlike the similar class in RDF4J, this is thread-safe and can merge to similar objects.
  42.  *
  43.  * @author  Fabrizio Giudici
  44.  *
  45.  **********************************************************************************************************************/
  46. @ThreadSafe
  47. public class ModelBuilder
  48.   {
  49.     private final Model model = new TreeModel();

  50.     @Nonnull private final Resource[] contexts;

  51.     /*******************************************************************************************************************
  52.      *
  53.      *
  54.      *
  55.      ******************************************************************************************************************/
  56.     public ModelBuilder (@Nonnull final Resource ... contexts)
  57.       {
  58.         this.contexts = contexts;
  59.       }

  60.     /*******************************************************************************************************************
  61.      *
  62.      *
  63.      *
  64.      ******************************************************************************************************************/
  65.     @Nonnull
  66.     public synchronized Model toModel()
  67.       {
  68.         return new TreeModel(model);
  69.       }

  70.     /*******************************************************************************************************************
  71.      *
  72.      *
  73.      *
  74.      ******************************************************************************************************************/
  75.     @Nonnull
  76.     public synchronized ModelBuilder with (@Nonnull final Resource subject,
  77.                                            @Nonnull final IRI predicate,
  78.                                            @Nonnull final Value object,
  79.                                            @Nonnull final Resource... contexts)
  80.       {
  81.         model.add(subject, predicate, object, contexts);
  82.         return this;
  83.       }

  84.     /*******************************************************************************************************************
  85.      *
  86.      *
  87.      *
  88.      ******************************************************************************************************************/
  89.     @Nonnull
  90.     public synchronized ModelBuilder with (@Nonnull final Resource subjext,
  91.                                            @Nonnull final IRI predicate,
  92.                                            @Nonnull final Optional<Value> optionalObject,
  93.                                            @Nonnull final Resource... contexts)
  94.       {
  95.         return optionalObject.map(object -> ModelBuilder.this.with(subjext, predicate, object, contexts)).orElse(this);
  96.       }

  97.     /*******************************************************************************************************************
  98.      *
  99.      *
  100.      *
  101.      ******************************************************************************************************************/
  102.     @Nonnull
  103.     public synchronized ModelBuilder withOptional (@Nonnull final Optional<? extends Resource> optionalSubject,
  104.                                                    @Nonnull final IRI predicate,
  105.                                                    @Nonnull final Value object)
  106.       {
  107.         return optionalSubject.map(subject -> ModelBuilder.this.with(subject, predicate, object)).orElse(this);
  108.       }

  109.     /*******************************************************************************************************************
  110.      *
  111.      *
  112.      *
  113.      ******************************************************************************************************************/
  114.     @Nonnull
  115.     public synchronized ModelBuilder withOptional (@Nonnull final Resource subject,
  116.                                                    @Nonnull final IRI predicate,
  117.                                                    @Nonnull final Optional<? extends Value> optionalObject)
  118.       {
  119.         return optionalObject.map(object -> ModelBuilder.this.with(subject, predicate, object)).orElse(this);
  120.       }

  121.     /*******************************************************************************************************************
  122.      *
  123.      *
  124.      *
  125.      ******************************************************************************************************************/
  126.     @Nonnull
  127.     public synchronized ModelBuilder withOptional (@Nonnull final Optional<? extends Resource> optionalSubject,
  128.                                                    @Nonnull final IRI predicate,
  129.                                                    @Nonnull final Optional<? extends Value> optionalObject)
  130.       {
  131.         return optionalObject.map(object -> withOptional(optionalSubject, predicate, object)).orElse(this);
  132.       }

  133.     /*******************************************************************************************************************
  134.      *
  135.      *
  136.      *
  137.      ******************************************************************************************************************/
  138.     @Nonnull
  139.     public synchronized ModelBuilder with (@Nonnull final List<? extends Resource> subjects,
  140.                                            @Nonnull final IRI predicate,
  141.                                            @Nonnull final Value object)
  142.       {
  143.         subjects.forEach(subject -> ModelBuilder.this.with(subject, predicate, object)); // FIXME ?? this = withOptional(...)
  144.         return this;
  145.       }

  146.     /*******************************************************************************************************************
  147.      *
  148.      *
  149.      *
  150.      ******************************************************************************************************************/
  151.     @Nonnull
  152.     public synchronized ModelBuilder with (@Nonnull final List<? extends Resource> subjects,
  153.                                            @Nonnull final IRI predicate,
  154.                                            @Nonnull final List<? extends Value> objects)
  155.       {
  156.         assert subjects.size() == objects.size();

  157.         for (int i = 0; i < subjects.size(); i++)
  158.           {
  159.             ModelBuilder.this.with(subjects.get(i), predicate, objects.get(i)); // FIXME ?? this = withOptional(...)
  160.           }

  161.         return this;
  162.       }

  163.     /*******************************************************************************************************************
  164.      *
  165.      *
  166.      *
  167.      ******************************************************************************************************************/
  168.     @Nonnull
  169.     public synchronized ModelBuilder with (@Nonnull final Resource subject,
  170.                                            @Nonnull final IRI predicate,
  171.                                            @Nonnull final Stream<? extends Value> objects)
  172.       {
  173.         objects.forEach(object -> ModelBuilder.this.with(subject, predicate, object)); // FIXME ?? this = withOptional(...)
  174.         return this;
  175.       }

  176.     /*******************************************************************************************************************
  177.      *
  178.      *
  179.      *
  180.      ******************************************************************************************************************/
  181.     @Nonnull
  182.     public synchronized ModelBuilder withOptional (@Nonnull final Optional<? extends Resource> subject,
  183.                                                    @Nonnull final IRI predicate,
  184.                                                    @Nonnull final Stream<? extends Value> objects)
  185.       {
  186.         if (subject.isPresent())
  187.           {
  188.             objects.forEach(object -> withOptional(subject, predicate, object)); // FIXME ?? this = withOptional(...)
  189.           }

  190.         return this;
  191.       }

  192.     /*******************************************************************************************************************
  193.      *
  194.      *
  195.      *
  196.      ******************************************************************************************************************/
  197.     @Nonnull
  198.     public synchronized ModelBuilder with (@Nonnull final Statement statement)
  199.       {
  200.         model.add(statement);
  201.         return this;
  202.       }

  203.     /*******************************************************************************************************************
  204.      *
  205.      *
  206.      *
  207.      ******************************************************************************************************************/
  208.     @Nonnull
  209.     public synchronized ModelBuilder with (@Nonnull final Optional<ModelBuilder> optionalBuiilder)
  210.       {
  211.         optionalBuiilder.ifPresent(ModelBuilder.this::with);
  212.         return this;
  213.       }

  214.     /*******************************************************************************************************************
  215.      *
  216.      *
  217.      *
  218.      ******************************************************************************************************************/
  219.     @Nonnull
  220.     public synchronized ModelBuilder with (@Nonnull final ModelBuilder other)
  221.       {
  222.         return ModelBuilder.this.with(other.toModel());
  223.       }

  224.     /*******************************************************************************************************************
  225.      *
  226.      *
  227.      *
  228.      ******************************************************************************************************************/
  229.     @Nonnull
  230.     public synchronized ModelBuilder with (@Nonnull final Model other)
  231.       {
  232.         other.forEach(model::add);
  233.         return this;
  234.       }

  235.     /*******************************************************************************************************************
  236.      *
  237.      *
  238.      *
  239.      ******************************************************************************************************************/
  240.     @Nonnull
  241.     public synchronized ModelBuilder with (@Nonnull final List<ModelBuilder> others)
  242.       {
  243.         others.stream().map(ModelBuilder::toModel).forEach(m -> m.forEach(model::add));
  244.         return this;
  245.       }
  246.   }