View Javadoc
1   /*
2    * This file is part of ***  M y C o R e  ***
3    * See http://www.mycore.de/ for details.
4    *
5    * MyCoRe is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    *
10   * MyCoRe is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with MyCoRe.  If not, see <http://www.gnu.org/licenses/>.
17   */
18  package org.mycore.access.facts;
19  
20  import java.util.Collection;
21  import java.util.HashSet;
22  import java.util.Optional;
23  import java.util.Set;
24  import java.util.StringJoiner;
25  
26  import org.mycore.access.facts.model.MCRFact;
27  import org.mycore.access.facts.model.MCRFactComputable;
28  
29  /**
30   * This class holds all facts which are validated as 'true'
31   * If an identical fact is request again during the rules processing
32   * the result is taken from here and won't be calculated again.
33   * 
34   * Internally it also stores the fact computers, for easier access.
35   * Fact computers are usually the conditions parsed from the rules.xml.
36   *  
37   * @author Robert Stephan
38   *
39   */
40  public class MCRFactsHolder {
41  
42      private Collection<MCRFactComputable<MCRFact<?>>> computers;
43  
44      private final Set<MCRFact<?>> facts = new HashSet<MCRFact<?>>();
45  
46      public MCRFactsHolder(Collection<MCRFactComputable<MCRFact<?>>> computers) {
47          this.computers = computers;
48      }
49  
50      public void add(MCRFact<?> fact) {
51          facts.add(fact);
52      }
53  
54      public boolean isFact(String factName, String term) {
55          Optional<MCRFact<?>> osc = facts.stream()
56              .filter(f -> factName.equals(f.getName()))
57              .filter(f -> term.equals(f.getTerm()))
58              .findFirst();
59          return osc.isPresent();
60      }
61  
62      public Optional<MCRFact<?>> require(String factName, MCRFactComputable<MCRFact<?>> factComputer) {
63          Optional<MCRFact<?>> osc = facts.stream().filter(f -> factName.equals(f.getName())).findFirst();
64          if (osc.isPresent()) {
65              return osc;
66          } else {
67              Optional<MCRFact<?>> fact = factComputer.computeFact(this);
68              if (fact.isPresent()) {
69                  facts.add(fact.get());
70                  return fact;
71              }
72          }
73          return Optional.empty();
74      }
75  
76      @SuppressWarnings("unchecked")
77      public <F extends MCRFact<?>> Optional<F> require(String factName) {
78          Optional<F> osc = (Optional<F>) facts.stream().filter(f -> factName.equals(f.getName())).findFirst();
79          if (osc.isPresent()) {
80              return osc;
81          } else {
82              Optional<MCRFactComputable<MCRFact<?>>> theComputer = computers.stream()
83                  .filter(c -> factName.equals(c.getFactName())).findFirst();
84              if (theComputer.isPresent()) {
85                  Optional<MCRFact<?>> fact = theComputer.get().computeFact(this);
86                  if (fact.isPresent()) {
87                      facts.add(fact.get());
88                      return (Optional<F>) fact;
89                  }
90              }
91          }
92          return Optional.empty();
93      }
94  
95      @Override
96      public String toString() {
97          StringJoiner sj = new StringJoiner(" & ");
98          facts.stream().forEach(f -> sj.add(f.toString()));
99          return sj.toString();
100     }
101 }