1 | /*
|
2 | * @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
|
3 | * @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
|
4 | * @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
|
5 | */
|
6 |
|
7 | import {abstractMethodFail} from '../assert';
|
8 | import {Enum} from '../Enum';
|
9 |
|
10 |
|
11 | /**
|
12 | * Strategy for querying a temporal object.
|
13 | *
|
14 | * Queries are a key tool for extracting information from temporal objects.
|
15 | * They exist to externalize the process of querying, permitting different
|
16 | * approaches, as per the strategy design pattern.
|
17 | * Examples might be a query that checks if the date is the day before February 29th
|
18 | * in a leap year, or calculates the number of days to your next birthday.
|
19 | *
|
20 | * The {@link TemporalField} interface provides another mechanism for querying
|
21 | * temporal objects. That interface is limited to returning a `long`.
|
22 | * By contrast, queries can return any type.
|
23 | *
|
24 | * There are two equivalent ways of using a {@link TemporalQuery}.
|
25 | * The first is to invoke the method on this interface directly.
|
26 | * The second is to use {@link TemporalAccessor#query}:
|
27 | * <pre>
|
28 | * // these two lines are equivalent, but the second approach is recommended
|
29 | * temporal = thisQuery.queryFrom(temporal);
|
30 | * temporal = temporal.query(thisQuery);
|
31 | * </pre>
|
32 | * It is recommended to use the second approach, {@link query},
|
33 | * as it is a lot clearer to read in code.
|
34 | *
|
35 | * The most common implementations are method references, such as
|
36 | * {@link LocalDate::from} and {@link ZoneId::from}.
|
37 | * Further implementations are on {@link TemporalQueries}.
|
38 | * Queries may also be defined by applications.
|
39 | *
|
40 | * ### Specification for implementors
|
41 | *
|
42 | * This interface places no restrictions on the mutability of implementations,
|
43 | * however immutability is strongly recommended.
|
44 | *
|
45 | * @interface
|
46 | */
|
47 | export class TemporalQuery extends Enum {
|
48 | /**
|
49 | * Queries the specified temporal object.
|
50 | *
|
51 | * This queries the specified temporal object to return an object using the logic
|
52 | * encapsulated in the implementing class.
|
53 | * Examples might be a query that checks if the date is the day before February 29th
|
54 | * in a leap year, or calculates the number of days to your next birthday.
|
55 | *
|
56 | * There are two equivalent ways of using this method.
|
57 | * The first is to invoke this method directly.
|
58 | * The second is to use {@link TemporalAccessor#query}:
|
59 | * <pre>
|
60 | * // these two lines are equivalent, but the second approach is recommended
|
61 | * temporal = thisQuery.queryFrom(temporal);
|
62 | * temporal = temporal.query(thisQuery);
|
63 | * </pre>
|
64 | * It is recommended to use the second approach, {@link query},
|
65 | * as it is a lot clearer to read in code.
|
66 | *
|
67 | * ### Specification for implementors
|
68 | *
|
69 | * The implementation must take the input object and query it.
|
70 | * The implementation defines the logic of the query and is responsible for
|
71 | * documenting that logic.
|
72 | * It may use any method on {@link TemporalAccessor} to determine the result.
|
73 | * The input object must not be altered.
|
74 | *
|
75 | * The input temporal object may be in a calendar system other than ISO.
|
76 | * Implementations may choose to document compatibility with other calendar systems,
|
77 | * or reject non-ISO temporal objects by querying the chronology (see {@link TemporalQueries#chronology}).
|
78 | *
|
79 | * This method may be called from multiple threads in parallel.
|
80 | * It must be thread-safe when invoked.
|
81 | *
|
82 | * @param {TemporalAccessor} temporal the temporal object to query, not null
|
83 | * @return the queried value, may return null to indicate not found
|
84 | * @throws DateTimeException if unable to query
|
85 | * @throws ArithmeticException if numeric overflow occurs
|
86 | */
|
87 | // eslint-disable-next-line no-unused-vars
|
88 | queryFrom(temporal){
|
89 | abstractMethodFail('queryFrom');
|
90 | }
|
91 |
|
92 | }
|
93 |
|
94 | /**
|
95 | * Factory to create something similar to the JSR-310 {TemporalQuery} interface, takes a function and returns a new TemporalQuery object that presents that function
|
96 | * as the queryFrom() function.
|
97 | * @param name for the underlying Enum
|
98 | * @param queryFromFunction
|
99 | */
|
100 | export function createTemporalQuery(name, queryFromFunction) {
|
101 | class ExtendedTemporalQuery extends TemporalQuery {
|
102 |
|
103 | }
|
104 |
|
105 | ExtendedTemporalQuery.prototype.queryFrom = queryFromFunction;
|
106 | return new ExtendedTemporalQuery(name);
|
107 | }
|