Fix MatchBuilderPath documentation
[mdsal.git] / binding / mdsal-binding-api / src / main / java / org / opendaylight / mdsal / binding / api / query / QueryExpression.java
1 /*
2  * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.mdsal.binding.api.query;
9
10 import com.google.common.annotations.Beta;
11 import org.opendaylight.yangtools.concepts.Immutable;
12 import org.opendaylight.yangtools.yang.binding.DataObject;
13
14 /**
15  * An opaque query expression. A query execution results in a {@link QueryResult}, which is composed of zero or more
16  * objects of the same type. Implementations of this interface are expected to be effectively-immutable and therefore
17  * thread-safe and reusable.
18  *
19  * <p>
20  * While this interface does not expose any useful methods, it represents a well-defined concept, which is composed of
21  * three distinct parts:
22  * <ul>
23  *   <li>root path, which defines the subtree on which the expression is executed</li>
24  *   <li>select path, which is a strict subset of the root path and defines which objects should be selected</li>
25  *   <li>a set of predicates, which are to be evaluated on selected objects</li>
26  * </ul>
27  * When the expression is evaluated, its QueryResult will contain only those selected objects which also match all
28  * predicates in the expression.
29  *
30  * <p>
31  * For the purposes of illustration of how these three parts work together, let's imagine the following simple model:
32  *
33  * <pre>
34  *   module foo {
35  *     list foo {
36  *       key name;
37  *
38  *       leaf name {
39  *         type string;
40  *       }
41  *
42  *       leaf alias {
43  *         type string;
44  *       }
45  *
46  *       container bar {
47  *         list baz {
48  *           key id;
49  *
50  *           leaf id {
51  *             type uint64;
52  *           }
53  *
54  *           leaf value {
55  *             type string;
56  *           }
57  *         }
58  *       }
59  *     }
60  *   }
61  * </pre>
62  *
63  * <p>
64  * We have two nested lists, each having two leaves -- one addressable as a key, one a plain property. There is a number
65  * of different queries we could perform on such a model:
66  * <ol>
67  *   <li>select all {@code baz}es which have {@code value="foo"}</li>
68  *   <li>select all {@code baz}es under {@code foo[name="xyzzy"]}, which have {@code value="foo"}</li>
69  *   <li>select all {@code foo}s which have {@code alias="xyzzy"}</li>
70  *   <li>select all {@code foo}s which have {@code alias="xyzzy"} and contain a {@code baz[value="foo"]}</li>
71  * </ol>
72  *
73  * <p>
74  * Note how the first and second options differ in what is being searched:
75  * <ul>
76  *   <li>search for all {@code baz} entries needs to traverse all {@code foo} entries</li>
77  *   <li>search for all {@code baz} entries for {@code foo[name="xyzzy"]} needs to traverse only a single
78  *       directly-addressable entry.</li>
79  * </ul>
80  * The distinction here is made by selecting different root paths: the first will specify the entire {@code foo} list,
81  * while the second will select a specific {@code foo} entry.
82  *
83  * @param <T> Result object type
84  */
85 @Beta
86 public interface QueryExpression<T extends DataObject> extends Immutable {
87
88 }