-
Notifications
You must be signed in to change notification settings - Fork 242
/
BoundPojoModelPath.java
117 lines (97 loc) · 4.01 KB
/
BoundPojoModelPath.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*
* Hibernate Search, full-text search for your domain model
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.search.mapper.pojo.model.path.impl;
import org.hibernate.search.mapper.pojo.extractor.mapping.programmatic.ContainerExtractorPath;
import org.hibernate.search.mapper.pojo.extractor.impl.BoundContainerExtractorPath;
import org.hibernate.search.mapper.pojo.extractor.impl.ContainerExtractorBinder;
import org.hibernate.search.mapper.pojo.model.path.PojoModelPath;
import org.hibernate.search.mapper.pojo.model.path.PojoModelPathPropertyNode;
import org.hibernate.search.mapper.pojo.model.path.PojoModelPathValueNode;
import org.hibernate.search.mapper.pojo.model.path.binding.impl.PojoModelPathWalker;
import org.hibernate.search.mapper.pojo.model.spi.PojoTypeModel;
/**
* Represents an arbitrarily long access path bound to a specific POJO model.
* <p>
* This class and its various subclasses are similar to {@link PojoModelPath},
* except they provide information about the types they are bound to.
* As a result, they include type node. For instance the path could be:
* <code>
* Type A => property "propertyOfA" => extractor "MapValueExtractor" => Type B => property "propertyOfB"
* </code>
*/
public abstract class BoundPojoModelPath {
public static Walker walker(ContainerExtractorBinder containerExtractorBinder) {
return new Walker( containerExtractorBinder );
}
public static <T> BoundPojoModelPathOriginalTypeNode<T> root(PojoTypeModel<T> typeModel) {
return new BoundPojoModelPathOriginalTypeNode<>( null, typeModel );
}
BoundPojoModelPath() {
// Package-protected constructor
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder( getClass().getSimpleName() )
.append( "[" );
appendPath( builder );
builder.append( "]" );
return builder.toString();
}
public abstract BoundPojoModelPath getParent();
public abstract PojoTypeModel<?> getRootType();
public abstract PojoModelPath toUnboundPath();
abstract void appendSelfPath(StringBuilder builder);
private void appendPath(StringBuilder builder) {
BoundPojoModelPath parent = getParent();
if ( parent == null ) {
appendSelfPath( builder );
}
else {
parent.appendPath( builder );
builder.append( " => " );
appendSelfPath( builder );
}
}
abstract void appendSelfPath(PojoModelPath.Builder builder);
final void appendPath(PojoModelPath.Builder builder) {
BoundPojoModelPath parent = getParent();
if ( parent != null ) {
parent.appendPath( builder );
}
appendSelfPath( builder );
}
public static class Walker implements PojoModelPathWalker<
Void, BoundPojoModelPathTypeNode<?>,
BoundPojoModelPathPropertyNode<?, ?>,
BoundPojoModelPathValueNode<?, ?, ?>
> {
private final ContainerExtractorBinder containerExtractorBinder;
private Walker(ContainerExtractorBinder containerExtractorBinder) {
this.containerExtractorBinder = containerExtractorBinder;
}
@Override
public BoundPojoModelPathPropertyNode<?, ?> property(Void context, BoundPojoModelPathTypeNode<?> typeNode,
PojoModelPathPropertyNode pathNode) {
return typeNode.property( pathNode.propertyName() );
}
@Override
public BoundPojoModelPathValueNode<?, ?, ?> value(Void context, BoundPojoModelPathPropertyNode<?, ?> propertyNode,
PojoModelPathValueNode pathNode) {
return value( propertyNode, pathNode.extractorPath() );
}
@Override
public BoundPojoModelPathTypeNode<?> type(Void context, BoundPojoModelPathValueNode<?, ?, ?> valueNode) {
return valueNode.type();
}
public <P> BoundPojoModelPathValueNode<?, P, ?> value(BoundPojoModelPathPropertyNode<?, P> propertyNode,
ContainerExtractorPath extractorPath) {
BoundContainerExtractorPath<P, ?> boundExtractorPath = containerExtractorBinder
.bindPath( propertyNode.getPropertyModel().typeModel(), extractorPath );
return propertyNode.value( boundExtractorPath );
}
}
}