View Javadoc

1   /*
2    * Copyright 2015 Data Archiving and Networked Services (an institute of
3    * Koninklijke Nederlandse Akademie van Wetenschappen), King's College London,
4    * Georg-August-Universitaet Goettingen Stiftung Oeffentlichen Rechts
5    *
6    * Licensed under the EUPL, Version 1.1 or – as soon they will be approved by
7    * the European Commission - subsequent versions of the EUPL (the "Licence");
8    * You may not use this work except in compliance with the Licence.
9    * You may obtain a copy of the Licence at:
10   *
11   * https://joinup.ec.europa.eu/software/page/eupl
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the Licence is distributed on an "AS IS" basis,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the Licence for the specific language governing
17   * permissions and limitations under the Licence.
18   */
19  
20  package eu.ehri.project.persistence.utils;
21  
22  import com.google.common.base.Joiner;
23  import com.google.common.base.Preconditions;
24  import com.google.common.base.Splitter;
25  import com.google.common.collect.ImmutableList;
26  import com.google.common.collect.Lists;
27  
28  import java.util.List;
29  import java.util.NoSuchElementException;
30  
31  /**
32   * Class representing a path which points to some data in a bundle, i.e.
33   * pointing to the startDate attribute of the second hasDate relation of the
34   * first node that describes the top-level item would be:
35   * <p>
36   * describes[0]/hasDate[1]/startDate
37   * <p>
38   * Everything before the final slash is a PathSection and must indicate the
39   * relation name and the index of the desired item.
40   */
41  final class NestableDataPath {
42  
43      private static final String PATH_SEP = "/";
44      private static final Splitter splitter = Splitter.on(PATH_SEP).omitEmptyStrings();
45      private static final Joiner joiner = Joiner.on(PATH_SEP).skipNulls();
46  
47      private final List<PathSection> sections;
48      private final String terminus;
49  
50      private NestableDataPath(List<PathSection> sections, String terminus) {
51          Preconditions.checkNotNull(terminus);
52          this.sections = ImmutableList.copyOf(sections);
53          this.terminus = terminus;
54      }
55  
56      String getTerminus() {
57          return terminus;
58      }
59  
60      public PathSection current() {
61          return sections.get(0);
62      }
63  
64      public boolean isEmpty() {
65          return sections.isEmpty();
66      }
67  
68      public NestableDataPath next() {
69          if (sections.isEmpty())
70              throw new NoSuchElementException();
71          List<PathSection> ns = Lists.newArrayList(sections);
72          ns.remove(0);
73          return new NestableDataPath(ns, terminus);
74      }
75  
76      public static NestableDataPath fromString(String path) {
77          List<PathSection> sections = Lists.newArrayList();
78          List<String> ps = Lists.newArrayList(splitter.split(path));
79          String terminus = ps.remove(ps.size() - 1);
80          for (String s : ps)
81              sections.add(PathSection.fromString(s));
82          // If the last part of the path matches a pathsection, i.e.
83          // the pattern something[1]
84          try {
85              sections.add(PathSection.fromString(terminus));
86              return new NestableDataPath(sections, null);
87          } catch (Exception e) {
88              return new NestableDataPath(sections, terminus);
89          }
90      }
91  
92      public String toString() {
93          return joiner.join(joiner.join(sections), terminus);
94      }
95  }