View Javadoc
1   /*
2    * Copyright 2018 the original author or authors.
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *         http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  
17  package org.openehealth.ipf.commons.ihe.fhir.support;
18  
19  
20  import org.hl7.fhir.dstu3.model.Enumerations;
21  import org.hl7.fhir.dstu3.model.NamingSystem;
22  
23  import java.util.Objects;
24  import java.util.Optional;
25  import java.util.function.BinaryOperator;
26  import java.util.function.Function;
27  import java.util.function.Predicate;
28  import java.util.stream.Stream;
29  
30  /**
31   * Service for finding FHIR {@link NamingSystem} instances. Implementations should consider
32   * caching all known naming systems and select specific ones.
33   *
34   * @author Christian Ohr
35   * @since 3.3
36   */
37  public interface NamingSystemService {
38  
39      /**
40       * Finds all {@link NamingSystem} instances that match the provided {@link Predicate} and returns
41       * a stream of these matches.
42       *
43       * @param id ID of a NamingSystem bundle
44       * @param predicate predicate selecting a naming system
45       * @return a stream of {@link NamingSystem} instances that match the provided {@link Predicate}
46       */
47      Stream<NamingSystem> findNamingSystems(String id, Predicate<? super NamingSystem> predicate);
48  
49      /**
50       * Returns the first {@link NamingSystem} instances that match the provided {@link Predicate}
51       *
52       * @param id ID of a NamingSystem bundle
53       * @param predicate predicate selecting a naming system
54       * @return {@link NamingSystem} instance that match the provided {@link Predicate}
55       */
56      default Optional<NamingSystem> findFirstNamingSystem(String id, Predicate<? super NamingSystem> predicate) {
57          return findNamingSystems(id, predicate).findFirst();
58      }
59  
60      /**
61       * Returns the first active {@link NamingSystem} instances that match the provided type and value
62       *
63       * @param id ID of a NamingSystem bundle
64       * @param type  NamingSystem identifier type (oid, uuid, ...)
65       * @param value value
66       * @return {@link NamingSystem} instance that match the provided type and value
67       */
68      default Optional<NamingSystem> findActiveNamingSystemByTypeAndValue(String id, NamingSystem.NamingSystemIdentifierType type, String value) {
69          return findFirstNamingSystem(id, allOf(
70                  byTypeAndValue(type, value),
71                  byStatus(Enumerations.PublicationStatus.ACTIVE)));
72      }
73  
74      // Predicates
75  
76      static Predicate<NamingSystem> allOf(Predicate<NamingSystem>... predicates) {
77          return combine(Predicate::and, predicates);
78      }
79  
80      static Predicate<NamingSystem> anyOf(Predicate<NamingSystem>... predicates) {
81          return combine(Predicate::or, predicates);
82      }
83  
84      static Predicate<NamingSystem> combine(BinaryOperator<Predicate<NamingSystem>> op, Predicate<NamingSystem>... predicates) {
85          return predicates != null ?
86                  Stream.of(predicates).reduce(op).orElse(namingSystem -> false) :
87                  namingSystem -> false;
88      }
89  
90      static Predicate<NamingSystem> byTypeAndValue(NamingSystem.NamingSystemIdentifierType type, String value) {
91          return namingSystem -> namingSystem.getUniqueId().stream()
92                  .anyMatch(uniqueId -> uniqueId.getType() == type
93                          && value.equals(uniqueId.getValue()));
94      }
95  
96      static Predicate<NamingSystem> byId(String id) {
97          return namingSystem -> Objects.equals(id, namingSystem.getId());
98      }
99  
100     static Predicate<NamingSystem> byName(String name) {
101         return namingSystem -> Objects.equals(name, namingSystem.getName());
102     }
103 
104     static Predicate<NamingSystem> byKind(NamingSystem.NamingSystemType kind) {
105         return namingSystem -> Objects.equals(kind, namingSystem.getKind());
106     }
107 
108     static Predicate<NamingSystem> byStatus(Enumerations.PublicationStatus status) {
109         return namingSystem -> Objects.equals(status, namingSystem.getStatus());
110     }
111 
112     // Functions
113 
114     static Function<NamingSystem, String> getValueOfType(NamingSystem.NamingSystemIdentifierType type) {
115         return namingSystem -> namingSystem.getUniqueId().stream()
116                 .filter(uniqueId -> type == uniqueId.getType())
117                 .findFirst()
118                 .map(NamingSystem.NamingSystemUniqueIdComponent::getValue)
119                 .orElse(null);
120     }
121 }