• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

evolvedbinary / elemental / 982

29 Apr 2025 08:34PM UTC coverage: 56.409% (+0.007%) from 56.402%
982

push

circleci

adamretter
[feature] Improve README.md badges

28451 of 55847 branches covered (50.94%)

Branch coverage included in aggregate %.

77468 of 131924 relevant lines covered (58.72%)

0.59 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

76.06
/exist-core/src/main/java/org/exist/xquery/Cardinality.java
1
/*
2
 * Elemental
3
 * Copyright (C) 2024, Evolved Binary Ltd
4
 *
5
 * admin@evolvedbinary.com
6
 * https://www.evolvedbinary.com | https://www.elemental.xyz
7
 *
8
 * Use of this software is governed by the Business Source License 1.1
9
 * included in the LICENSE file and at www.mariadb.com/bsl11.
10
 *
11
 * Change Date: 2028-04-27
12
 *
13
 * On the date above, in accordance with the Business Source License, use
14
 * of this software will be governed by the Apache License, Version 2.0.
15
 *
16
 * Additional Use Grant: Production use of the Licensed Work for a permitted
17
 * purpose. A Permitted Purpose is any purpose other than a Competing Use.
18
 * A Competing Use means making the Software available to others in a commercial
19
 * product or service that: substitutes for the Software; substitutes for any
20
 * other product or service we offer using the Software that exists as of the
21
 * date we make the Software available; or offers the same or substantially
22
 * similar functionality as the Software.
23
 */
24
package org.exist.xquery;
25

26
import static org.exist.xquery.Cardinality.InternalValue.*;
27

28
/**
29
 * Defines <a href="https://www.w3.org/TR/xpath-31/#prod-xpath31-OccurrenceIndicator">XPath Occurrence Indicators</a>
30
 * (*,?,+), and additionally defines {@link #EMPTY_SEQUENCE}, and {@link #EXACTLY_ONE} for convenience.
31
 *
32
 * @author <a href="mailto:adam@evolvedbinary.com">Adam Retter</a>
33
 */
34
public enum Cardinality {
1✔
35

36
    EMPTY_SEQUENCE(ZERO),
1✔
37

38
    //TODO(AR) can we eliminate this?
1✔
39
    EXACTLY_ONE(ONE),
1✔
40

41
    //TODO(AR) eliminate this in favour of probably ONE_OR_MORE
1✔
42
    _MANY(MANY),
1✔
43

44
    /**
1✔
45
     * indicator '?'
46
     */
47
    ZERO_OR_ONE((byte)(ZERO | ONE)),
1✔
48

49
    /**
1✔
50
     * indicator '+'
51
     */
52
    ONE_OR_MORE((byte)(ONE | MANY)),
1✔
53

54
    /**
1✔
55
     * indicator '*'
56
     */
57
    ZERO_OR_MORE((byte)(ZERO | ONE | MANY));
1✔
58

59

60
    private final byte val;
61

62
    Cardinality(final byte val) {
1✔
63
        this.val = val;
1✔
64
    }
1✔
65

66
    /**
67
     * The cardinality represents a sequence of at least one value.
68
     *
69
     * @return true if the cardinality represents a sequence of at least one value, or false otherwise.
70
     */
71
    public boolean atLeastOne() {
72
        return (val & ZERO) == 0;
1✔
73
    }
74

75
    /**
76
     * The cardinality represents a sequence of at most one value.
77
     *
78
     * @return true if the cardinality represents a sequence of at most one value, or false otherwise.
79
     */
80
    public boolean atMostOne() {
81
        return (val & MANY) == 0;
1✔
82
    }
83

84
    /**
85
     * Tests whether this Cardinality is a sub-cardinality or equal
86
     * of {@code other}.
87
     *
88
     * @param other the other cardinality
89
     *
90
     * @return true if this is a sub-cardinality or equal cardinality of {@code other}.
91
     */
92
    public boolean isSubCardinalityOrEqualOf(final Cardinality other) {
93
        return (val | other.val) == other.val;
1✔
94
    }
95

96
    /**
97
     * Tests whether this Cardinality is a super-cardinality or equal
98
     * of {@code other}.
99
     *
100
     * @param other the other cardinality
101
     *
102
     * @return true if this is a super-cardinality or equal cardinality of {@code other}.
103
     */
104
    public boolean isSuperCardinalityOrEqualOf(final Cardinality other) {
105
        return (val & other.val) == other.val;
1✔
106
    }
107

108
    /**
109
     * Given two cardinalities, return a cardinality that is capable of
110
     * representing both,
111
     * i.e.: {@code a.isSubCardinalityOrEqualOf(max(a, b)) && b.isSubCardinalityOrEqualOf(max(a, b)) && b.max(a, b))}
112
     *
113
     * @param a the first cardinality
114
     * @param b the second cardinality
115
     *
116
     * @return the super cardinality
117
     */
118
    public static Cardinality superCardinalityOf(final Cardinality a, final Cardinality b) {
119
        final byte max = (byte)(a.val | b.val);
1✔
120
        for (final Cardinality cardinality : Cardinality.values()) {
1!
121
            if (cardinality.val == max) {
1✔
122
                return cardinality;
1✔
123
            }
124
        }
125
        throw new IllegalStateException();
×
126
    }
127

128
    /**
129
     * Get an XQuery notation representation of the cardinality.
130
     *
131
     * @return the XQuery notation
132
     */
133
    public String toXQueryCardinalityString() {
134
        // impossible
135
        return switch (this) {
1!
136
            case EMPTY_SEQUENCE -> "empty-sequence()";
×
137
            case EXACTLY_ONE -> "";
1✔
138
            case ZERO_OR_ONE -> "?";
1✔
139
            case _MANY, ONE_OR_MORE -> "+";
1✔
140
            case ZERO_OR_MORE -> "*";
1✔
141
            default -> throw new IllegalArgumentException("Unknown cardinality: " + name());
×
142
        };
143
    }
144

145
    /**
146
     * Get a human pronounceable description of the cardinality.
147
     *
148
     * @return a pronounceable description
149
     */
150
    public String getHumanDescription() {
151
        // impossible
152
        return switch (this) {
1!
153
            case EMPTY_SEQUENCE -> "empty";
1✔
154
            case EXACTLY_ONE -> "exactly one";
1✔
155
            case ZERO_OR_ONE -> "zero or one";
1✔
156
            case _MANY, ONE_OR_MORE -> "one or more";
1✔
157
            case ZERO_OR_MORE -> "zero or more";
1✔
158
            default -> throw new IllegalArgumentException("Unknown cardinality: " + name());
×
159
        };
160
    }
161

162
    /**
163
     * Get the Cardinality from an integer representation.
164
     *
165
     * @param intValue integer representation of cardinality
166
     *
167
     * @return the cardinality
168
     *
169
     * @deprecated You should not pass cardinality as integer values,
170
     *     this is for backwards compatibility with eXist-db
171
     */
172
    @Deprecated
173
    public static Cardinality fromInt(final int intValue) {
174
        for (final Cardinality cardinality : Cardinality.values()) {
×
175
            if (cardinality.val == intValue) {
×
176
                return cardinality;
×
177
            }
178
        }
179
        throw new IllegalArgumentException("No know cardinality for intValue: " + intValue);
×
180
    }
181

182
    static class InternalValue {
×
183
        static final byte ZERO = 1;
184
        static final byte ONE = 2;
185
        static final byte MANY = 4;
186
    }
187
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc