• 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

83.33
/exist-core/src/main/java/org/exist/xquery/functions/integer/NumberingPicture.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.functions.integer;
25

26
import org.exist.xquery.XPathException;
27

28
import java.math.BigInteger;
29
import java.util.HashMap;
30
import java.util.Locale;
31
import java.util.Map;
32
import java.util.Optional;
33

34
/**
35
 * Format numbers according to rule 9 (any other numbering sequence)
36
 * {@see https://www.w3.org/TR/xpath-functions-31/#formatting-integers}
37
 */
38
class NumberingPicture extends IntegerPicture {
39

40
    // Set up the code point ranges we accept as numberings.
41
    private static final Map<Integer, Integer> rangesForCodePoint = new HashMap<>();
1✔
42

43
    static {
44
        NumberingPicture.range(0x391, 0x3A9);
1✔
45
        NumberingPicture.range(0x3B1, 0x3C9);
1✔
46
        NumberingPicture.range('①', '⑳');
1✔
47
        NumberingPicture.range('⑴', '⒇');
1✔
48
        NumberingPicture.range('⒈', '⒛');
1✔
49
    }
1✔
50

51
    private final int indexCodePoint;
52
    private final int limitForRange;
53
    private final IntegerPicture defaultPicture;
54
    private final FormatModifier formatModifier;
55

56
    /**
57
     * Define a range using characters
58
     *
59
     * @param from first item in range (1)
60
     * @param to   last item in range (inclusive)
61
     */
62
    private static void range(final char from, final char to) {
63
        final char[] fromChars = {from};
1✔
64
        final char[] toChars = {to};
1✔
65
        NumberingPicture.rangesForCodePoint.put(Character.codePointAt(fromChars, 0), Character.codePointAt(toChars, 0));
1✔
66
    }
1✔
67

68
    /**
69
     * Define a range using code points
70
     *
71
     * @param from first item in range (1)
72
     * @param to   last item in range (inclusive)
73
     */
74
    private static void range(final int from, final int to) {
75
        NumberingPicture.rangesForCodePoint.put(from, to);
1✔
76
    }
1✔
77

78
    private NumberingPicture(final int indexCodePoint, final int limitForRange, final FormatModifier formatModifier) throws XPathException {
1✔
79
        this.indexCodePoint = indexCodePoint;
1✔
80
        this.limitForRange = limitForRange;
1✔
81
        this.defaultPicture = IntegerPicture.defaultPictureWithModifier(formatModifier);
1✔
82
        this.formatModifier = formatModifier;
1✔
83
    }
1✔
84

85
    /**
86
     * Try to create a numbering picture from an index code point
87
     * Check that the code point is in a known range,
88
     * and if it is then return the numbering picture for that range.
89
     * <p>
90
     * Otherwise,
91
     *
92
     * @param indexCodePoint codePoint which may be part of a numbering range
93
     * @param formatModifier format modifier to be used by a generated formatter
94
     * @return a numbering picture if the code point is in range, otherwise {@link Optional#empty()} }
95
     * @throws XPathException if the picture cannot be created
96
     */
97
    public static Optional<IntegerPicture> fromIndexCodePoint(final int indexCodePoint, final FormatModifier formatModifier) throws XPathException {
98
        if (!NumberingPicture.rangesForCodePoint.containsKey(indexCodePoint)) {
1✔
99
            return Optional.empty();
1✔
100
        }
101
        final int limitForRange = NumberingPicture.rangesForCodePoint.get(indexCodePoint);
1✔
102
        return Optional.of(new NumberingPicture(indexCodePoint, limitForRange, formatModifier));
1✔
103
    }
104

105
    /**
106
     * Format according to a numbering
107
     *
108
     * @param bigInteger the integer to format
109
     * @param locale     of the language to use in formatting
110
     * @return the formatted string output
111
     * @throws XPathException if something went wrong
112
     */
113
    @Override
114
    public String formatInteger(final BigInteger bigInteger, final Locale locale) throws XPathException {
115
        //spec says out of range should be formatted by "1"
116
        if (bigInteger.compareTo(BigInteger.valueOf(1)) < 0 || bigInteger.compareTo(BigInteger.valueOf(limitForRange - indexCodePoint + 1L)) > 0) {
1!
117
            return defaultPicture.formatInteger(bigInteger, locale);
1✔
118
        }
119

120
        final StringBuilder result = new StringBuilder();
1✔
121
        result.append(IntegerPicture.fromCodePoint(bigInteger.intValue() + indexCodePoint - 1));
1✔
122
        if (formatModifier.numbering == FormatModifier.Numbering.ORDINAL && bigInteger.compareTo(BigInteger.valueOf(Integer.MIN_VALUE)) >= 0 && bigInteger.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) <= 0) {
1!
123
            result.append(IntegerPicture.ordinalSuffix(bigInteger.intValue(), locale));
×
124
        }
125
        return result.toString();
1✔
126
    }
127
}
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