9
9
* Licensed under the Apache License, Version 2.0 (the "License");
10
10
* you may not use this file except in compliance with the License.
11
11
* You may obtain a copy of the License at
12
- *
12
+ *
13
13
* http://www.apache.org/licenses/LICENSE-2.0
14
- *
14
+ *
15
15
* Unless required by applicable law or agreed to in writing, software
16
16
* distributed under the License is distributed on an "AS IS" BASIS,
17
17
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21
21
*/
22
22
23
23
24
-
25
24
import com .yangdb .fuse .asg .strategy .AsgStrategy ;
26
25
import com .yangdb .fuse .model .Range ;
27
26
import com .yangdb .fuse .model .Tagged ;
36
35
import com .yangdb .fuse .model .query .entity .EndPattern ;
37
36
import com .yangdb .fuse .model .query .properties .BaseProp ;
38
37
import com .yangdb .fuse .model .query .properties .BasePropGroup ;
38
+ import com .yangdb .fuse .model .query .properties .EPropGroup ;
39
39
import com .yangdb .fuse .model .query .quant .Quant1 ;
40
40
import com .yangdb .fuse .model .query .quant .QuantBase ;
41
41
import com .yangdb .fuse .model .query .quant .QuantType ;
@@ -94,7 +94,7 @@ public void apply(AsgQuery query, AsgStrategyContext context) {
94
94
quant .get ().addNext (quantAsg );
95
95
} else {
96
96
// quant of type some exist -> add the inner or patterns after the quant
97
- addRelPattern (counter , query , quant .get (), relPattern ,endPattern .get ());
97
+ addRelPattern (counter , query , quant .get (), relPattern , endPattern .get ());
98
98
//remove pattern
99
99
parent .get ().removeNextChild (relPattern );
100
100
}
@@ -103,8 +103,47 @@ public void apply(AsgQuery query, AsgStrategyContext context) {
103
103
104
104
//replace all EndPatterns with its internal real entity
105
105
AsgQueryUtil .elements (query , EndPattern .class )
106
- .forEach (p -> ((AsgEBase ) p ).seteBase (p .geteBase ().getEndEntity ()));
106
+ .forEach (p -> replaceEndPattern (counter , p ));
107
+
108
+ }
109
+
110
+ /**
111
+ * replace end pattern with the actual type - including its possible filters
112
+ *
113
+ * @param counter
114
+ * @param p
115
+ */
116
+ public void replaceEndPattern (AtomicInteger counter , AsgEBase <EndPattern > p ) {
117
+ if (!p .geteBase ().getFilter ().isEmpty ()) {
118
+ //if end pattern is last in query - add quant for the purpose of the end-pattern filters
119
+ if (!p .hasNext ()) {
120
+ addEndPatternFilters (counter , p );
121
+ } else {
122
+ //if end pattern is not last in query - search for a quant right after
123
+ Optional <AsgEBase <QuantBase >> quantOp = AsgQueryUtil .nextAdjacentDescendant (p , QuantBase .class , 1 );
124
+ // if quant not present - add one and chain all childs to that quant
125
+ if (!quantOp .isPresent ()) {
126
+ AsgEBase <QuantBase > quantAsg = new AsgEBase <>(new Quant1 (counter .incrementAndGet (), QuantType .all ));
127
+ AsgQueryUtil .replaceParents (quantAsg ,p );
128
+ p .addNext (quantAsg );
129
+ }
130
+ // quant present - add end-pattern filter to quant
131
+ quantOp = AsgQueryUtil .nextAdjacentDescendant (p , QuantBase .class , 1 );
132
+ EPropGroup ePropGroup = new EPropGroup (p .geteBase ().getFilter ()).clone (counter .incrementAndGet ());
133
+ quantOp .get ().addNext (new AsgEBase <>(ePropGroup ));
134
+ }
135
+ }
136
+ //change endPattern type to actual type
137
+ ((AsgEBase ) p ).seteBase (p .geteBase ().getEndEntity ());
138
+ }
107
139
140
+ public QuantBase addEndPatternFilters (AtomicInteger counter , AsgEBase <EndPattern > p ) {
141
+ QuantBase newQuant = new Quant1 (counter .incrementAndGet (), QuantType .all );
142
+ AsgEBase <QuantBase > quantAsg = new AsgEBase <>(newQuant );
143
+ EPropGroup ePropGroup = new EPropGroup (p .geteBase ().getFilter ()).clone (counter .incrementAndGet ());
144
+ quantAsg .addNext (new AsgEBase <>(ePropGroup ));
145
+ p .addNext (quantAsg );
146
+ return newQuant ;
108
147
}
109
148
110
149
/**
@@ -117,11 +156,11 @@ public void apply(AsgQuery query, AsgStrategyContext context) {
117
156
private void addRelPattern (AtomicInteger counter , AsgQuery query , AsgEBase <Quant1 > quantAsg , AsgEBase <RelPattern > relPattern , AsgEBase <EndPattern > endPattern ) {
118
157
Range range = relPattern .geteBase ().getLength ();
119
158
//duplicate the rel pattern according to the range, range should already be validated by the validator
120
- LongStream .rangeClosed (range .getLower () , range .getUpper ())
159
+ LongStream .rangeClosed (range .getLower (), range .getUpper ())
121
160
//this is the Root some quant all pattern premutations will be added to...
122
161
.forEach (value -> {
123
162
//if value == 0 remove the RelPattern entirely
124
- if (value == 0 ) {
163
+ if (value == 0 ) {
125
164
//take the path after the end pattern section (if exists) & add it as no hop pattern to the Quant
126
165
if (endPattern .hasNext ()) {
127
166
final AsgEBase <? extends EBase > nextAfterEndPattern = endPattern .getNext ().get (0 );
@@ -145,28 +184,29 @@ private void addRelPattern(AtomicInteger counter, AsgQuery query, AsgEBase<Quant
145
184
146
185
/**
147
186
* rel pattern premutation generator
187
+ *
148
188
* @param value
149
189
* @param relPattern
150
190
* @param endPattern
151
191
* @return
152
192
*/
153
- private AsgEBase <? extends EBase > addPath (AtomicInteger counter ,long value , AsgEBase <RelPattern > relPattern , AsgEBase <EndPattern > endPattern ) {
193
+ private AsgEBase <? extends EBase > addPath (AtomicInteger counter , long value , AsgEBase <RelPattern > relPattern , AsgEBase <EndPattern > endPattern ) {
154
194
final AtomicReference <AsgEBase <? extends EBase >> current = new AtomicReference <>();
155
195
LongStream .rangeClosed (1 , value )
156
196
.forEach (step -> {
157
- AsgEBase <? extends EBase > node = buildStep (counter ,relPattern , endPattern );
197
+ AsgEBase <? extends EBase > node = buildStep (counter , relPattern , endPattern );
158
198
if (current .get () == null ) {
159
199
current .set (node );
160
200
} else {
161
201
//the build step returns a cloned pattern of [rel:Rel]-....->(endPattern:Entity)->...
162
202
//
163
- if (!(current .get ().geteBase () instanceof QuantBase )) {
203
+ if (!(current .get ().geteBase () instanceof QuantBase )) {
164
204
final AsgEBase <Quant1 > quant = new AsgEBase <>(new Quant1 (counter .incrementAndGet (), QuantType .all ));
165
- AsgQueryUtil .addAsNext (quant ,current .get ());
205
+ AsgQueryUtil .addAsNext (quant , current .get ());
166
206
current .set (quant );
167
207
} else {
168
208
//knowing that the rel pattern has a shape of a line not a tree get the last Descendant
169
- current .set (AsgQueryUtil .nextDescendant (current .get (),EndPattern .class ).get ());
209
+ current .set (AsgQueryUtil .nextDescendant (current .get (), EndPattern .class ).get ());
170
210
}
171
211
current .get ().addNext (AsgQueryUtil .ancestorRoot (node ).get ());
172
212
current .set (node );
@@ -179,11 +219,12 @@ private AsgEBase<? extends EBase> addPath(AtomicInteger counter,long value, AsgE
179
219
180
220
/**
181
221
* build a new complete rel->pattern step cloned from existing step
222
+ *
182
223
* @param relPattern
183
224
* @param endPattern
184
225
* @return
185
226
*/
186
- private AsgEBase <? extends EBase > buildStep (AtomicInteger counter ,AsgEBase <RelPattern > relPattern , AsgEBase <EndPattern > endPattern ) {
227
+ private AsgEBase <? extends EBase > buildStep (AtomicInteger counter , AsgEBase <RelPattern > relPattern , AsgEBase <EndPattern > endPattern ) {
187
228
188
229
RelPattern pattern = relPattern .geteBase ();
189
230
List <AsgEBase <? extends EBase >> belowList = new ArrayList <>(relPattern .getB ());
0 commit comments